/*
 *  Zendollarjs;
 *  version: 1.0.2;
 *  author: rpsffx(郑约淼);
 *  date: 2017.09.17;
 */
!(function(window, undefined) {
    "no use strict";
    (function() {
        setScript();
        include("https://cdn.bootcss.com/device.js/0.2.7/device.min.js");
        document.getElementsByTagName('style')[0].innerHTML += "body{display:none !important;visibility:hidden !important;opacity:0 !important;width:0 !important;height:0 !important;pointer-events:none !important;}";
    })();
    var userAgent = navigator.userAgent,
        isChrome = userAgent.indexOf("Chrome") > -1 && userAgent.indexOf("Safari") > -1,
        isFF = userAgent.indexOf("Firefox") > -1,
        isOpera = userAgent.indexOf("Opera") > -1,
        isSafari = userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1,
        isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera,
        isEdge = userAgent.indexOf("Edge") > -1,
        version = '1.0.2',
        isLoaded = false,
        newStorage = {},
        allEvents = 'click dblclick contextmenu mouseover mouseout mouseenter mouseleave mousedown mousemove mouseup focus blur focusin focusout select change submit reset search keydown keypress keyup scroll wheel resize load unload abort beforeunload error hashchange pageshow pagehide input copy cut paste afterprint beforeprint formchange forminput invalid drag dragend dragenter dragleave dragover dragstart drop canplay canplaythrough durationchange emptied ended loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting message online offline popstate show storage redo undo toggle animationstart animationiteration animationend transitionend',
        $ = function(selector) {
            return new $.fn.init(selector);
        },
        Zendollar = $,
        _$ = window.$,
        _Zendollar = window.Zendollar,
        $on = $.on = function(obj, event, fn) {
            var events = event.split(' ');
            for (let ev of events) {
                var fnName = getFuncName(fn) || Math.random() + '' + Math.random(),
                    func = function() {
                        fn.apply(obj, arguments);
                    };
                obj.funByEv = obj.funByEv || {};
                obj.funByEv[ev] = obj.funByEv[ev] || [];
                var Json = {};
                Json[fnName] = func;
                obj.funByEv[ev].push(Json);
                if (obj.addEventListener) {
                    obj.addEventListener(ev, func, false);
                } else {
                    obj.attachEvent('on' + ev, func);
                }
            }
        },
        $off = $.off = function(obj, event, fn) {
            var events = event.split(' ');
            for (let ev of events) {
                var fnName = getFuncName(fn),
                    iBtn = false,
                    len = obj.funByEv[ev].length;
                if (fn && fnName) {
                    for (let i = 0; i < len; i++) {
                        for (let j in obj.funByEv[ev][i]) {
                            if (j === fnName) {
                                obj.removeEventListener ? obj.removeEventListener(ev, obj.funByEv[ev][i][fnName], false) : obj.dettachEvent('on' + ev, obj.funByEv[ev][i][fnName]);
                                iBtn = true;
                            }
                        }
                        if (iBtn) break;
                    }
                } else {
                    for (let i = 0; i < len; i++) {
                        for (let k in obj.funByEv[ev][i]) {
                            obj.removeEventListener ? obj.removeEventListener(ev, obj.funByEv[ev][i][k], false) : obj.detachEvent('on' + ev, obj.funByEv[ev][i][k]);
                        }
                    }
                }
            }
        },
        $load = $.load = function(fn) {
            if (isLoaded === false && version === '1.0.2') {
                $on(window, 'load', fn);
                document.getElementsByTagName('style')[0].innerHTML = document.getElementsByTagName('style')[0].innerHTML.replace(/body{display:none !important;visibility:hidden !important;opacity:0 !important;width:0 !important;height:0 !important;pointer-events:none !important;}/, ".Zendollar{transition:all 0.5s ease-in-out !important;}");
                addLink("https://cdn.bootcss.com/mobi.css/2.0.0-beta.1/mobi.min.css");
                document.body.classList.add("Zendollar");
                isLoaded = true;
            }
        },
        $ready = $.ready = function(fn) {
            if (isLoaded === false && version === '1.0.2') {
                $on(document, 'DOMContentLoaded', fn);
                document.getElementsByTagName('style')[0].innerHTML = document.getElementsByTagName('style')[0].innerHTML.replace(/body{display:none !important;visibility:hidden !important;opacity:0 !important;width:0 !important;height:0 !important;pointer-events:none !important;}/, ".Zendollar{transition:all 0.5s ease-in-out !important;}");
                addLink("https://cdn.bootcss.com/mobi.css/2.0.0-beta.1/mobi.min.css");
                document.body.classList.add("Zendollar");
                isLoaded = true;
            }
        },
        $lag = $.lag = function(fn) {
            if (isLoaded === false && version === '1.0.2') {
                if (arguments.length === 1) {
                    setTimeout(fn.bind(window), 1000);
                } else if (arguments.length === 2) {
                    if (arguments[1] <= 0) arguments[1] = 0;
                    setTimeout(fn.bind(window), arguments[1]);
                }
                document.getElementsByTagName('style')[0].innerHTML = document.getElementsByTagName('style')[0].innerHTML.replace(/body{display:none !important;visibility:hidden !important;opacity:0 !important;width:0 !important;height:0 !important;pointer-events:none !important;}/, ".Zendollar{transition:all 0.5s ease-in-out !important;}");
                addLink("https://cdn.bootcss.com/mobi.css/2.0.0-beta.1/mobi.min.css");
                document.body.classList.add("Zendollar");
                isLoaded = true;
            }
        },
        $loadImage = $.loadImage = function(arr) {
            var newimages = [],
                loadedimages = 0,
                postaction = $noop(),
                arr = (typeof arr != "object") ? [arr] : arr;

            function imageloadpost() {
                loadedimages++;
                if (loadedimages === arr.length) {
                    postaction(newimages);
                }
            }
            for (let i = 0, len = arr.length; i < len; i++) {
                newimages[i] = new Image();
                newimages[i].src = arr[i];
                newimages[i].onload = function() {
                    imageloadpost();
                };
                newimages[i].onerror = function() {
                    imageloadpost();
                };
            }
            return {
                done: function(f) {
                    postaction = f || postaction;
                }
            };
        },
        $per = $.per = function(object, callback, args) {
            var name,
                i = 0,
                length = object.length;
            if (typeof object === 'string') {
                object = $query(object);
            }
            if (args) {
                if (length === undefined) {
                    for (name in object) {
                        if (callback.apply(object[name], args) === false) {
                            break;
                        }
                    }
                } else {
                    for (; i < length;) {
                        if (callback.apply(object[i++], args) === false) {
                            break;
                        }
                    }
                }
            } else {
                if (length === undefined) {
                    for (name in object) {
                        if (callback.call(object[name], name, object[name]) === false) {
                            break;
                        }
                    }
                } else {
                    for (let value = object[0]; i < length && callback.call(value, i, value) !== false; value = object[++i]) {}
                }
            }
            return object;
        },
        $each = $.each = function(object, callback) {
            var type = (function() {
                switch (object.constructor) {
                    case Object:
                        return 'Object';
                        break;
                    case Array:
                        return 'Array';
                        break;
                    case NodeList:
                        return 'NodeList';
                        break;
                    default:
                        return 'null';
                        break;
                }
            })();
            if (type === 'Array' || type === 'NodeList') {
                [].every.call(object, function(v, i) {
                    return callback.call(v, i, v) === false ? false : true;
                });
            } else if (type === 'Object') {
                for (let i in object) {
                    if (callback.call(object[i], i, object[i]) === false) {
                        break;
                    }
                }
            }
        },
        $map = $.map = function(arr, fn) {
            var results = [];
            for (let i = 0; i < arr.length; i++) {
                results.push(fn(arr[i], i));
            }
            return results;
        },
        $unique = $.unique = function(arr) {
            for (let i = 0; i < arr.length; i++) {
                for (let j = i + 1; j < arr.length; j++) {
                    if (arr[i] === arr[j]) {
                        arr.splice(j, 1);
                        j--;
                    }
                }
            }
            return arr.sort();
        },
        $make = $.make = function(arrayLike) {
            return Array.prototype.slice.call(arrayLike);
        },
        $grep = $.grep = function(arr, callback, invert) {
            var temp = [];
            for (let i = 0, l = arr.length; i < l; i++) {
                if (callback(arr[i]) === invert) {
                    temp.push(arr[i]);
                }
            }
            return temp;
        },
        $merge = $.merge = function(arr1, arr2) {
            if ($isArray(arr1) === true && $isArray(arr2) === true) {
                arr1.push.apply(arr1, arr2);
            } else {
                Object.assign(arr1, arr2);
            }
            return arr1;
        },
        $trim = $.trim = function(str, dir) {
            if (!dir) {
                return str.trim();
            } else if (dir === 'left') {
                return str.leftTrim();
            } else if (dir === 'right') {
                return str.rightTrim();
            } else if (dir === 'all') {
                return str.trimAll();
            }
        },
        $call = $.call = function(element, targetSelector, events, handler) {
            $on(element, events, function(event) {
                var targets = $query(targetSelector),
                    target = event.target;
                if (targets.indexOf(target) != -1) {
                    return handler.apply(target, arguments);
                }
            });
        },
        $debounce = $.debounce = function(func, wait, immediate) {
            var timeout;
            return function() {
                var context = this,
                    args = arguments,
                    later = function() {
                        timeout = null;
                        if (!immediate) func.apply(context, args);
                    },
                    callNow = immediate && !timeout;
                clearTimeout(timeout);
                timeout = setTimeout(later, wait);
                if (callNow) func.apply(context, args);
            };
        },
        $poll = $.poll = function(fn, callback, errback, timeout, interval) {
            var endTime = Number(new Date()) + (timeout || 2000);
            interval = interval || 100;
            (function p() {
                if (fn()) {
                    callback();
                } else if (Number(new Date()) < endTime) {
                    setTimeout(p, interval);
                } else {
                    errback(new Error('timed out for ' + fn + ': ' + arguments));
                }
            })();
        },
        $once = $.once = function(fn, context) {
            var result;
            return function() {
                if (fn) {
                    result = fn.apply(context || this, arguments);
                    fn = null;
                }
                return result;
            };
        },
        $find = $.find = function(curEle, tagName) {
            var nodeList = curEle.child(),
                ary = [];
            if (/MSIE(6|7|8)/.test(navigator.userAgent)) {
                for (let i = 0; i < nodeList.length; i++) {
                    var curNode = nodeList[i];
                    if (curNode.nodeType === 1) {
                        ary[ary.length] = curNode;
                    }
                }
            } else {
                ary = $make(curEle.child());
            }
            if (typeof tagName === "string") {
                for (let k = 0; k < ary.length; k++) {
                    var curTag = ary[k];
                    if (curTag.nodeName.toLowerCase() !== tagName.toLowerCase()) {
                        ary.splice(k, 1);
                        k--;
                    }
                }
            }
            return ary;
        },
        $matches = $.matches = function(el, selector) {
            return matchesElement(el, selector);
        },
        $query = $.query = function(selector) {
            var arr = [],
                nodes = document.getElementsByTagName('*');
            for (let i = 0, len = nodes.length; i < len; i++) {
                if (matchesElement(nodes[i], selector) === true) {
                    arr.push(nodes[i]);
                }
            }
            return arr;
        },
        $filter = $.filter = function(selector, filterFn) {
            var elements = $query(selector),
                arr = [];
            for (let i = elements.length; i--;) {
                if (filterFn(elements[i])) {
                    arr.unshift(elements[i]);
                }
            }
            return arr;
        },
        $until = $.until = function(el, selector, filter) {
            var arr = [];
            el = el.parentNode;
            while (el && !matchesElement(el, selector)) {
                if (!filter) {
                    arr.push(el);
                } else {
                    if (matchesElement(el, filter)) {
                        arr.push(el);
                    }
                }
                el = el.parentNode;
            }
            return arr;
        },
        $index = $.index = function(current, obj) {
            if (arguments.length === 2) {
                for (let i = 0, length = obj.length; i < length; i++) {
                    if (obj[i] === current) {
                        return i;
                    }
                }
            } else if (arguments.length === 1) {
                return current.parentNode.child().indexOf(current);
            }
        },
        $inArray = $.inArray = function(arr, obj) {
            var i = arr.length;
            while (i--) {
                if (arr[i] === obj) {
                    return true;
                }
            }
            return false;
        },
        $isParent = $.isParent = function(obj, parentObj) {
            while (obj != undefined && obj != null && obj.tagName.toUpperCase() != 'BODY') {
                if (obj === parentObj) {
                    return true;
                }
                obj = obj.parentNode;
            }
            return false;
        },
        $isInViewport = $.isInViewport = function(element) {
            var rect = element.getBoundingClientRect(),
                html = document.documentElement;
            return (
                rect.top >= 0 &&
                rect.left >= 0 &&
                rect.bottom <= (window.innerHeight || html.clientHeight) &&
                rect.right <= (window.innerWidth || html.clientWidth)
            );
        },
        $isHit = $.isHit = function(obj1, obj2) {
            var l1 = obj1.offsetLeft,
                t1 = obj1.offsetTop,
                r1 = l1 + obj1.offsetWidth,
                b1 = t1 + obj1.offsetHeight,
                l2 = obj2.offsetLeft,
                t2 = obj2.offsetTop,
                r2 = l2 + obj2.offsetWidth,
                b2 = t2 + obj2.offsetHeight;
            if (l1 > r2 || t1 > b2 || r1 < l2 || b1 < t2) {
                return false;
            } else {
                return true;
            }
        },
        $isWindow = $.isWindow = function(obj) {
            return obj !== null && obj !== undefined && obj === obj.window;
        },
        $isArray = $.isArray = function(arr) {
            return Object.prototype.toString.call(arr) === '[object Array]';
        },
        $isFunction = $.isFunction = function(fn) {
            return Object.prototype.toString.call(fn) === '[object Function]';
        },
        $isNumber = $.isNumber = function(num) {
            return Object.prototype.toString.call(num) === '[object Number]';
        },
        $isString = $.isString = function(str) {
            return Object.prototype.toString.call(str) === '[object String]';
        },
        $isBoolean = $.isBoolean = function(bool) {
            return Object.prototype.toString.call(bool) === '[object Boolean]';
        },
        $isObject = $.isObject = function(obj) {
            return Object.prototype.toString.call(obj) === '[object Object]';
        },
        $isNull = $.isNull = function(arg) {
            return Object.prototype.toString.call(arg) === '[object Null]';
        },
        $isUndefined = $.isUndefined = function(arg) {
            return Object.prototype.toString.call(arg) === '[object Undefined]';
        },
        $is = $.is = function(arg) {
            return Object.prototype.toString.call(arg).replace(/object\s+/, "").replace(/\[|\]/g, "");
        },
        $print = $.print = function() {
            if (arguments.length === 1) {
                return console.log(arguments[0]);
            } else if (arguments.length === 0) {
                return console.log("");
            }
        },
        $noop = $.noop = function() {},
        $noConflict = $.noConflict = function(deep) {
            if (window.$ === $) {
                window.$ = _$;
            }
            if (deep && deep === true && window.Zendollar === Zendollar) {
                window.Zendollar = _Zendollar;
            }
            return Zendollar;
        },
        $eval = $.eval = function(code) {
            return window.eval.call(window, code);
        },
        $time = $.time = function(startTime, endTime, diffType) {
            var date = new Date(),
                year = date.getFullYear(),
                month = date.getMonth() + 1,
                data = date.getDate(),
                hours = date.getHours(),
                minute = date.getMinutes(),
                second = date.getSeconds(),
                time = year + "-" + fnW(month) + "-" + fnW(data) + " " + fnW(hours) + ":" + fnW(minute) + ":" + fnW(second);
            if (arguments.length === 0) {
                return time;
            } else {
                return GetDateDiff(startTime, endTime, diffType);
            }
        },
        $getCSS = $.getCSS = function(selector, styles) {
            var el = $query(selector);
            for (let i = 0, len = el.length; i < len; i++) {
                if (styles) {
                    return el[i].css(styles);
                } else {
                    var list = '',
                        allStyle = document.defaultView.getComputedStyle(el[i], null);
                    for (let i of allStyle) {
                        if (typeof allStyle[i] != 'string') continue;
                        list += i + ": " + allStyle[i] + ";\n";
                    }
                    return list;
                }
            }
        },
        $addCSS = $.addCSS = function() {
            for (let i = 0, len = arguments.length; i < len; i++) {
                var Style = document.getElementsByTagName('style');
                Style[0].innerHTML += arguments[i];
            }
            return this;
        },
        $setCSS = $.setCSS = function(selector, styles) {
            var el = $query(selector);
            for (let property in styles) {
                if (!styles.hasOwnProperty(property)) continue;
                for (let i = 0, len = el.length; i < len; i++) {
                    if (el[i].style.setProperty) {
                        el[i].style.setProperty(property.uncamelize(), styles[property], null);
                    } else {
                        el[i].style[property.camelize()] = styles[property];
                    }
                }
                return true;
            }
        },
        $clientWidth = $.clientWidth = function(bool) {
            if (!bool || bool === false) {
                return window.innerWidth;
            } else if (bool === true) {
                return Math.max(document.body.clientWidth, document.documentElement.clientWidth);
            } else if (typeof bool === 'object') {
                return bool.clientWidth;
            }
        },
        $clientHeight = $.clientHeight = function(bool) {
            if (!bool || bool === false) {
                return window.innerHeight;
            } else if (bool === true) {
                return Math.max(document.body.clientHeight, document.documentElement.clientHeight);
            } else if (typeof bool === 'object') {
                return bool.clientHeight;
            }
        },
        $scrollLeft = $.scrollLeft = function() {
            if (arguments.length === 0) {
                if (isFF) {
                    return document.documentElement.scrollLeft;
                } else {
                    return document.body.scrollLeft;
                }
            } else if (arguments.length === 1) {
                if (typeof arguments[0] === 'object') {
                    return arguments[0].scrollLeft;
                } else {
                    return document.documentElement.scrollLeft = document.body.scrollLeft = arguments[0];
                }
            }
        },
        $scrollTop = $.scrollTop = function() {
            if (arguments.length === 0) {
                if (isFF) {
                    return document.documentElement.scrollTop;
                } else {
                    return document.body.scrollTop;
                }
            } else if (arguments.length === 1) {
                if (typeof arguments[0] === 'object') {
                    return arguments[0].scrollTop;
                } else {
                    return document.documentElement.scrollTop = document.body.scrollTop = arguments[0];
                }
            }
        },
        $scrollWidth = $.scrollWidth = function() {
            if (arguments.length === 0) {
                return Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
            } else if (arguments.length === 1) {
                return arguments[0].scrollWidth;
            }
        },
        $scrollHeight = $.scrollHeight = function() {
            if (arguments.length === 0) {
                return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
            } else if (arguments.length === 1) {
                return arguments[0].scrollHeight;
            }
        },
        $outerWidth = $.outerWidth = function(el, includeMargin) {
            var height = el.offsetWidth;
            if (includeMargin) {
                var style = el.currentStyle || getComputedStyle(el);
                height += parseInt(style.marginLeft) + parseInt(style.marginRight);
            }
            return height;
        },
        $outerHeight = $.outerHeight = function(el, includeMargin) {
            var height = el.offsetHeight;
            if (includeMargin) {
                var style = el.currentStyle || getComputedStyle(el);
                height += parseInt(style.marginTop) + parseInt(style.marginBottom);
            }
            return height;
        },
        $screen = $.screen = function() {
            var width = window.screen.width,
                height = window.screen.height,
                left,
                top;
            if (isFF) {
                left = window.screenX;
                top = window.screenY;
            } else {
                left = window.screenLeft;
                top = window.screenTop;
            }
            if (arguments.length > 0) {
                width = arguments[0].getBoundingClientRect().width;
                height = arguments[0].getBoundingClientRect().height;
                left = arguments[0].getBoundingClientRect().left;
                top = arguments[0].getBoundingClientRect().top;
            }
            return {
                width: width,
                height: height,
                left: left,
                top: top
            };
        },
        $imageSize = $.imageSize = function(img) {
            var naturalSize = {};
            if (window.naturalWidth && window.naturalHeight) {
                naturalSize.width = img.width;
                naturalSize.height = img.height;
            } else {
                var image = new Image();
                image.src = img.src;
                naturalSize.width = image.width;
                naturalSize.height = image.height;
            }
            return {
                width: naturalSize.width,
                height: naturalSize.height
            };
        },
        $scrollTo = $.scrollTo = function(target) {
            var scrollT = $scrollTop(),
                timer = null;
            if (target === 'top') {
                target = 0;
            } else if (target === 'bottom') {
                target = $scrollHeight();
            }
            if (typeof target === 'object') {
                target = target.offset().top;
            }
            window.onscroll = function() {
                if (getScrollTop() + getWindowHeight() === getScrollHeight()) {
                    cancelAnimationFrame(timer);
                }
            };
            if (scrollT > target) {
                function scrollUp() {
                    timer = requestAnimationFrame(scrollUp);
                    var scrollT = $scrollTop(),
                        step = Math.floor(-scrollT / 6);
                    document.documentElement.scrollTop = document.body.scrollTop = step + scrollT;
                    if (scrollT <= target) {
                        document.body.scrollTop = document.documentElement.scrollTop = target;
                        cancelAnimationFrame(timer);
                    }
                }
                timer = requestAnimationFrame(scrollUp);
            } else if (scrollT === 0) {
                function goScroll() {
                    timer = requestAnimationFrame(goScroll);
                    var scrollT = $scrollTop(),
                        step = Math.floor(300 / 3 * 0.7);
                    document.documentElement.scrollTop = document.body.scrollTop = step + scrollT;
                    if (scrollT >= target) {
                        document.body.scrollTop = document.documentElement.scrollTop = target;
                        cancelAnimationFrame(timer);
                    }
                }
                timer = requestAnimationFrame(goScroll);
            } else if (scrollT < target) {
                function scrollDown() {
                    timer = requestAnimationFrame(scrollDown);
                    var scrollT = $scrollTop(),
                        step = Math.floor(scrollT / 6);
                    document.documentElement.scrollTop = document.body.scrollTop = step + scrollT;
                    if (scrollT >= target) {
                        document.body.scrollTop = document.documentElement.scrollTop = target;
                        cancelAnimationFrame(timer);
                    }
                }
                timer = requestAnimationFrame(scrollDown);
            } else if (target === scrollT) {
                return false;
            }
        },
        $event = $.event = function() {
            var e = window.event || arguments.callee.caller.arguments[0];
            return {
                x: e.clientX,
                y: e.clientY,
                scrollX: e.pageX,
                scrollY: e.pageY,
                offsetX: e.offsetX || e.layerX,
                offsetY: e.offsetY || e.layerY,
                stop: e.stopPropagation(),
                prevent: e.preventDefault(),
                target: e.target || e.srcElement,
                relatedTarget: e.relatedTarget,
                type: e.type,
                alt: e.altKey,
                ctrl: e.ctrlKey,
                shift: e.shiftKey,
                meta: e.metaKey,
                fromElement: e.fromElement,
                toElement: e.toElement,
                screenX: e.screenX,
                screenY: e.screenY,
                code: e.keyCode || e.which,
                bubbles: e.bubbles,
                cancelable: e.cancelable,
                currentTarget: e.currentTarget,
                timeStamp: e.timeStamp,
                eventPhase: e.eventPhase,
                button: e.button
            };
        },
        $extend = $.extend = function(out) {
            out = out || {};
            for (let i = 1; i < arguments.length; i++) {
                if (!arguments[i])
                    continue;
                for (let key in arguments[i]) {
                    if (arguments[i].hasOwnProperty(key))
                        out[key] = arguments[i][key];
                }
            }
            return out;
        },
        $deepExtend = $.deepExtend = function(out) {
            out = out || {};
            for (let i = 1; i < arguments.length; i++) {
                var obj = arguments[i];
                if (!obj)
                    continue;
                for (let key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        if (typeof obj[key] === 'object')
                            out[key] = $deepExtend(out[key], obj[key]);
                        else
                            out[key] = obj[key];
                    }
                }
            }
            return out;
        },
        $data = $.data = function(options) {
            var self = this;
            this.data = options.data;
            this.methods = options.methods;
            Object.keys(this.data).forEach(function(key) {
                self.proxyKeys(key);
            });
            observe(this.data);
            new Compile(options.el, this);
            if (options.mounted) {
                options.mounted.call(this);
            }
        },
        $ajax = $.ajax = function() {
            var ajaxData = {
                type: arguments[0].type || "GET",
                url: arguments[0].url || "",
                async: arguments[0].async || "true",
                data: arguments[0].data || null,
                dataType: arguments[0].dataType || "text",
                contentType: arguments[0].contentType || "application/x-www-form-urlencoded",
                beforeSend: arguments[0].beforeSend || $noop(),
                success: arguments[0].success || $noop(),
                error: arguments[0].error || $noop()
            };
            ajaxData.beforeSend();
            var xhr = createxmlHttpRequest();
            xhr.responseType = ajaxData.dataType;
            xhr.open(ajaxData.type, ajaxData.url, ajaxData.async);
            xhr.setRequestHeader("Content-Type", ajaxData.contentType);
            xhr.send(convertData(ajaxData.data));
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        ajaxData.success(xhr.response);
                    } else {
                        ajaxData.error();
                    }
                }
            };
        },
        $setCookie = $.setCookie = function(cname, cvalue, exdays) {
            var d = new Date();
            d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
            var expires = "expires=" + d.toUTCString();
            document.cookie = cname + "=" + cvalue + "; " + expires;
        },
        $getCookie = $.getCookie = function(cname) {
            var name = cname + "=",
                ca = document.cookie.split(';');
            for (let i = 0; i < ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0) === ' ') c = c.substring(1);
                if (c.indexOf(name) != -1) return c.substring(name.length, c.length);
            }
            return "";
        },
        $clearCookie = $.clearCookie = function(name) {
            return $setCookie(name, "", -1);
        },
        $checkCookie = $.checkCookie = function() {
            var user = $getCookie("username");
            if (user != "") {
                alert("Welcome again " + user);
            } else {
                user = prompt("Please enter your name:", "");
                if (user != "" && user != null) {
                    $setCookie("username", user, 365);
                }
            }
        },
        $getURLParam = $.getURLParam = function(strParamName, url) {
            var strReturn = "",
                strHref = url.toLowerCase();
            if (strHref.indexOf("?") > -1) {
                var strQueryString = strHref.substr(strHref.indexOf("?") + 1).toLowerCase(),
                    aQueryString = strQueryString.split("&");
                for (let iParam = 0; iParam < aQueryString.length; iParam++) {
                    if (aQueryString[iParam].indexOf(strParamName.toLowerCase() + "=") > -1) {
                        var aParam = aQueryString[iParam].split("=");
                        strReturn = aParam[1];
                        break;
                    }
                }
            }
            return strReturn;
        },
        $parseHTML = $.parseHTML = function(markup) {
            var parser = new DOMParser(),
                doc = parser.parseFromString(markup, "text/html");
            return $make(doc.body.children);
        },
        $parseURL = $.parseURL = (function() {
            var a;
            return function(url) {
                if (!a) a = document.createElement('a');
                a.href = url;
                return a.href;
            };
        })(),
        $JSON = $.JSON = (function() {
            var get = function(url, data, callback) {
                    if (arguments.length < 3) {
                        callback = arguments[1];
                    } else {
                        data = arguments[1];
                        callback = arguments[2];
                    }
                    return $ajax({
                        type: "GET",
                        url: url,
                        data: data,
                        dataType: "json",
                        success: callback
                    });
                },
                post = function(url, data, callback) {
                    if (arguments.length < 3) {
                        callback = arguments[1];
                    } else {
                        data = arguments[1];
                        callback = arguments[2];
                    }
                    return $ajax({
                        type: "POST",
                        url: url,
                        data: data,
                        dataType: "json",
                        success: callback
                    });
                },
                toJSON = function(json) {
                    return JSON.parse(json);
                },
                toString = function(json) {
                    return JSON.stringify(json);
                };
            return {
                get: get,
                post: post,
                toJSON: toJSON,
                toString: toString
            };
        })(),
        $listener = $.listener = (function() {
            var attachFunctionList = {},
                notify = function(notifyName) {
                    var args = $make(arguments, 1);
                    attachFunctionList[notifyName].fun.apply(attachFunctionList[notifyName].scope, args);
                    return this;
                },
                attach = function(notifyName, callback) {
                    if (typeof notifyName === "string" && typeof callback === "function") {
                        attachFunctionList[notifyName] = {
                            fun: callback
                        };
                    }
                    return this;
                };
            return {
                notify: notify,
                attach: attach
            };
        })();
    (function() {
        $.fn = Element.prototype;
        $.dt = Date.prototype;
        $.st = String.prototype;
        $.ar = Array.prototype;
        $.fx = Function.prototype;
        $.add = Object.defineProperties;
    })();
    $.add($.fn, {
        init: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                if (selector) {
                    if (typeof selector === 'string') {
                        selector = selector.replace(/^\s+|\s+$/g, "").replace(/\;/g, "");
                        var arr = [],
                            nodes = document.body.getElementsByTagName('*'),
                            nodez = document.getElementsByTagName('*');
                        if (selector.charAt(0) === '#') {
                            arr.push(document.getElementById(selector.substring(1)));
                            return arr[0];
                        } else if (selector.charAt(0) === '.') {
                            return $make(document.getElementsByClassName(selector.substring(1)));
                        } else if (selector.charAt(0) === '[' && selector.charAt(selector.length - 1) === ']') {
                            for (let i = 0, len = nodes.length; i < len; i++) {
                                if (selector.indexOf('=') === -1) {
                                    if (nodes[i].hasAttribute(selector.substring(1, selector.length - 1)) === true) {
                                        arr.push(nodes[i]);
                                    }
                                } else if (selector.indexOf('=') != -1) {
                                    var j = selector.indexOf('=');
                                    if (nodes[i].hasAttribute(selector.substring(1, j)) === true && nodes[i].getAttribute(selector.substring(1, j)) === selector.substring(j + 1, selector.length - 1)) {
                                        arr.push(nodes[i]);
                                    }
                                }
                            }
                            return arr;
                        } else if (selector.charAt(0) === '{' && selector.charAt(selector.length - 1) === '}' && selector.indexOf(':') != -1) {
                            for (let i = 0, len = nodes.length; i < len; i++) {
                                selector = selector.replace(/\;/g, "").replace(/\:\s+/, ":");
                                var j = selector.indexOf(':');
                                if (document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue(selector.substring(1, j)) === selector.substring(j + 1, selector.length - 1) || document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue(selector.substring(1, j)) === hexToRgb(selector.substring(j + 1, selector.length - 1)) || document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue(selector.substring(1, j)) === colorToRgb(selector.substring(j + 1, selector.length - 1))) {
                                    arr.push(nodes[i]);
                                }
                            }
                            return arr;
                        } else if (selector.charAt(0) === ':') {
                            if (selector === ':header') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName === 'H1' || nodes[i].tagName === 'H2' || nodes[i].tagName === 'H3' || nodes[i].tagName === 'H4' || nodes[i].tagName === 'H5' || nodes[i].tagName === 'H6') {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':empty') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && nodes[i].hasChildNodes() === false) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':first') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && nodes[i].parentNode === document.body) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':hide') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('display') === 'none' || document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('visibility') === 'hidden' || document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('opacity') === 0) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':show') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('display') !== 'none' && document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('visibility') !== 'hidden' && document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('opacity') !== 0) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':even') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && $index(nodes[i]) % 2 === 0) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':odd') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && $index(nodes[i]) % 2 === 1) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].hasAttribute('type') === true && nodes[i].getAttribute('type') === selector.substring(1)) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            }
                        } else if (selector.charAt(0) === '<' && selector.charAt(selector.length - 1) === '>') {
                            if (selector.indexOf('</') != -1) {
                                for (let i = 0, len = nodez.length; i < len; i++) {
                                    var str = removeWhiteNode(nodez[i]).outerHTML.replace(/[\r\n]/g, "");
                                    if (selector.indexOf('style=') === -1 && nodez[i].hasAttribute('style') === true) {
                                        str = str.replace(/(\s+style=)(".*?")/, '');
                                    }
                                    str = str.replace(/(\s+data-display=)(".*?")/, '');
                                    if (str === selector || str === selector.replace(/\s\/>/g, ">") || str === selector.replace(/\/>/g, ">")) {
                                        arr.push(nodez[i]);
                                    }
                                }
                                return arr;
                            } else if (selector.indexOf('</') === -1) {
                                for (let i = 0, len = nodez.length; i < len; i++) {
                                    var str = removeWhiteNode(nodez[i]).outerHTML.replace(/[\r\n]/g, "");
                                    if (selector.indexOf('style=') === -1 && nodez[i].hasAttribute('style') === true) {
                                        str = str.replace(/(\s+style=)(".*?")/, '');
                                    }
                                    str = str.replace(/(\s+data-display=)(".*?")/, '');
                                    if (str.substring(0, str.indexOf('>') + 1).search(selector) != -1 || str.substring(0, str.indexOf('>') + 1).search(selector.replace(/\s\/>/g, ">")) != -1 || str.substring(0, str.indexOf('>') + 1).search(selector.replace(/\/>/g, ">")) != -1) {
                                        arr.push(nodez[i]);
                                    }
                                }
                                return arr;
                            }
                        } else if (selector.charAt(0) === '@') {
                            return $make(document.getElementsByName(selector.substring(1)));
                        } else {
                            if (selector === 'body') {
                                arr.push(document.body);
                                return arr[0];
                            } else if (selector === 'forms') {
                                return $make(document.forms);
                            } else if (selector === 'head') {
                                arr.push(document.getElementsByTagName('head')[0]);
                                return arr[0];
                            } else {
                                return $make(document.getElementsByTagName(selector));
                            }
                        }
                    } else if (typeof selector === 'function') {
                        return $ready(selector);
                    } else if (typeof selector === 'object') {
                        if (selector === document) {
                            return window.self.document;
                        } else if (selector === window) {
                            return window.self;
                        } else {
                            return selector;
                        }
                    } else if (typeof selector === 'number') {
                        return document.body.children[selector];
                    }
                } else {
                    if (document.body.hasChildNodes() === false) {
                        return document.body;
                    } else {
                        return document.body.children[0]
                    }
                }
            }
        },
        $: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                if (arguments.length === 1) {
                    if (typeof selector === 'string') {
                        selector = selector.replace(/^\s+|\s+$/g, "");
                        var arr = [],
                            nodes = this.getElementsByTagName('*');
                        if (selector.charAt(0) === '#') {
                            arr.push(this.getElementById(selector.substring(1)));
                            return arr[0];
                        } else if (selector.charAt(0) === '.') {
                            return $make(this.getElementsByClassName(selector.substring(1)));
                        } else if (selector.charAt(0) === '[' && selector.charAt(selector.length - 1) === ']') {
                            for (let i = 0, len = nodes.length; i < len; i++) {
                                if (selector.indexOf('=') === -1) {
                                    if (nodes[i].hasAttribute(selector.substring(1, selector.length - 1)) === true) {
                                        arr.push(nodes[i]);
                                    }
                                } else if (selector.indexOf('=') != -1) {
                                    var j = selector.indexOf('=');
                                    if (nodes[i].hasAttribute(selector.substring(1, j)) === true && nodes[i].getAttribute(selector.substring(1, j)) === selector.substring(j + 1, selector.length - 1)) {
                                        arr.push(nodes[i]);
                                    }
                                }
                            }
                            return arr;
                        } else if (selector.charAt(0) === '{' && selector.charAt(selector.length - 1) === '}' && selector.indexOf(':') != -1) {
                            for (let i = 0, len = nodes.length; i < len; i++) {
                                selector = selector.replace(/\;/g, "").replace(/\:\s+/, ":");
                                var j = selector.indexOf(':');
                                if (document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue(selector.substring(1, j)) === selector.substring(j + 1, selector.length - 1) || document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue(selector.substring(1, j)) === hexToRgb(selector.substring(j + 1, selector.length - 1)) || document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue(selector.substring(1, j)) === colorToRgb(selector.substring(j + 1, selector.length - 1))) {
                                    arr.push(nodes[i]);
                                }
                            }
                            return arr;
                        } else if (selector.charAt(0) === ':') {
                            if (selector === ':header') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName === 'H1' || nodes[i].tagName === 'H2' || nodes[i].tagName === 'H3' || nodes[i].tagName === 'H4' || nodes[i].tagName === 'H5' || nodes[i].tagName === 'H6') {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':empty') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && nodes[i].hasChildNodes() === false) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':first') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && nodes[i].parentNode === this) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':hide') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('display') === 'none' || document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('visibility') === 'hidden' || document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('opacity') === 0) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':show') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('display') !== 'none' && document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('visibility') !== 'hidden' && document.defaultView.getComputedStyle(nodes[i], null).getPropertyValue('opacity') !== 0) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':even') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && $index(nodes[i]) % 2 === 0) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector === ':odd') {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].tagName != 'SCRIPT' && $index(nodes[i]) % 2 === 1) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    if (nodes[i].hasAttribute('type') === true && nodes[i].getAttribute('type') === selector.substring(1)) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            }
                        } else if (selector.charAt(0) === '<' && selector.charAt(selector.length - 1) === '>') {
                            if (selector.indexOf('</') != -1) {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    var str = removeWhiteNode(nodes[i]).outerHTML.replace(/[\r\n]/g, "");
                                    if (selector.indexOf('style=') === -1 && nodes[i].hasAttribute('style') === true) {
                                        str = str.replace(/(\s+style=)(".*?")/, '');
                                    }
                                    str = str.replace(/(\s+data-display=)(".*?")/, '');
                                    if (str === selector || str === selector.replace(/\s\/>/g, ">") || str === selector.replace(/\/>/g, ">")) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            } else if (selector.indexOf('</') === -1) {
                                for (let i = 0, len = nodes.length; i < len; i++) {
                                    var str = removeWhiteNode(nodes[i]).outerHTML.replace(/[\r\n]/g, "");
                                    if (selector.indexOf('style=') === -1 && nodes[i].hasAttribute('style') === true) {
                                        str = str.replace(/(\s+style=)(".*?")/, '');
                                    }
                                    str = str.replace(/(\s+data-display=)(".*?")/, '');
                                    if (str.substring(0, str.indexOf('>') + 1).search(selector) != -1 || str.substring(0, str.indexOf('>') + 1).search(selector.replace(/\s\/>/g, ">")) != -1 || str.substring(0, str.indexOf('>') + 1).search(selector.replace(/\/>/g, ">")) != -1) {
                                        arr.push(nodes[i]);
                                    }
                                }
                                return arr;
                            }
                        } else if (selector.charAt(0) === '@') {
                            return $make(this.getElementsByName(selector.substring(1)));
                        } else {
                            return $make(this.getElementsByTagName(selector));
                        }
                    } else if (typeof selector === 'number') {
                        if (this.hasChildNodes() === true) {
                            return this.children[selector];
                        } else {
                            return this;
                        }
                    } else if (typeof selector === 'object') {
                        for (let keys in selector) {
                            if (selector.hasOwnProperty(keys)) {
                                if (keys === 'go') {
                                    var i = String(selector[keys]).indexOf('('),
                                        j = String(selector[keys]).indexOf(')'),
                                        event = String(selector[keys]).substring(i + 1, j).replace(/\s+/g, "").match(/[\$][a-z]*/g).join(",").replace(/\$/g, "").split(",");
                                    for (let evs of event) {
                                        this['on' + evs] = selector[keys];
                                    }
                                } else if (keys === 'stop') {
                                    var event = selector[keys].split(" ");
                                    for (let evs of event) {
                                        this['on' + evs] = null;
                                    }
                                } else if (keys === 'watch') {
                                    for (let props in selector[keys]) {
                                        this[keys].call(this, props, selector[keys][props]);
                                    }
                                } else {
                                    this['on' + keys] = selector[keys];
                                    this[keys] = selector[keys];
                                    this.style[keys] = selector[keys];
                                }
                            }
                        }
                        return this;
                    } else if (typeof selector === 'function') {
                        return selector.apply(this, arguments);
                    }
                } else if (arguments.length === 0) {
                    if (this.hasChildNodes() === true) {
                        return this.children[0];
                    } else {
                        return this;
                    }
                }
            }
        },
        Zendollar: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.$(arguments[0]);
            }
        },
        on: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(ev, fn) {
                if (this) $on(this, ev, fn);
                return this;
            }
        },
        off: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(ev, fn) {
                if (this) {
                    if (arguments.length === 1) {
                        $off(this, ev);
                        return this;
                    } else if (arguments.length === 2) {
                        $off(this, ev, fn);
                        return this;
                    }
                }
            }
        },
        go: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(ev, fn) {
                if (this) {
                    var event = ev.split(" ");
                    for (let evs of event) {
                        this['on' + evs] = fn;
                    }
                }
                return this;
            }
        },
        stop: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(ev) {
                if (this) {
                    var event = ev.split(" ");
                    for (let evs of event) {
                        this['on' + evs] = null;
                    }
                }
                return this;
            }
        },
        delegate: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector, ev, fn) {
                if (this) $call(this, selector, ev, fn);
                return this;
            }
        },
        wide: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (arguments.length === 0) {
                    return this.offsetWidth;
                } else if (arguments.length === 1) {
                    this.style.width = arguments[0] + 'px';
                    return this;
                }
            }
        },
        high: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (arguments.length === 0) {
                    return this.offsetHeight;
                } else if (arguments.length === 1) {
                    this.style.height = arguments[0] + 'px';
                    return this;
                }
            }
        },
        trigger: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(type, data) {
                var event = document.createEvent('HTMLEvents');
                event.initEvent(type, true, true);
                event.data = data || {}
                event.eventName = type;
                event.target = this;
                this.dispatchEvent(event);
                return this;
            }
        },
        toggle: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var Arguments = arguments;

                function addToggle(obj) {
                    var count = 0;
                    $on(obj, 'click', function() {
                        Arguments[count++ % Arguments.length].call(obj);
                    });
                }
                addToggle(this);
                return this;
            }
        },
        hover: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(fn1, fn2) {
                $on(this, 'mouseover', fn1);
                $on(this, 'mouseout', fn2);
                return this;
            }
        },
        press: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(fn1, fn2) {
                $on(this, 'mousedown', fn1);
                $on(this, 'mouseup', fn2);
                return this;
            }
        },
        follow: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(ev1, fn1, ev2, fn2) {
                var flag = true;
                $on(this, ev1, function() {
                    if (flag) {
                        fn1.apply(this, arguments);
                        if (ev1 && fn1) {
                            flag = false;
                        }
                    }
                    if (!flag) {
                        $on(this, ev2, fn2);
                    }
                });
                return this;
            }
        },
        watch: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(prop, fn) {
                var oldVal = this[prop],
                    newVal = null,
                    that = this,
                    oldTimer = null,
                    newTimer = null,
                    count = 0;
                clearInterval(newTimer);
                clearTimeout(oldTimer);
                newTimer = setInterval(function() {
                    newVal = that[prop];
                    oldTimer = setTimeout(function() {
                        oldVal = that[prop];
                    }, 4);
                    if (newVal != oldVal) {
                        count++;
                        watcher(newVal, oldVal, count);
                    }

                    function watcher(newVal, oldVal, count) {
                        fn.call(that, newVal, oldVal, count);
                    }
                }, 4);
                return this;
            }
        },
        clean: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(val) {
                var str,
                    flag = true;
                if (val) {
                    str = val;
                } else {
                    str = this.value;
                }
                this.onfocus = function() {
                    if (flag) {
                        this.value = null;
                    }
                }
                this.onblur = function() {
                    if (!this.value) {
                        this.value = str;
                        flag = true;
                    } else {
                        flag = false;
                    }
                }
                return this;
            }
        },
        css: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var option;
                if (arguments.length > 0) {
                    option = arguments[0];
                    if (2 === arguments.length) {
                        option = {}, option[arguments[0]] = arguments[1];
                    }
                    if ('object' === typeof option) {
                        for (let key in option) {
                            if (option.hasOwnProperty(key)) {
                                this.style[key] = option[key];
                            }
                        }
                    } else if ('string' === typeof option) {
                        return document.defaultView.getComputedStyle(this, null).getPropertyValue(option);
                    }
                }
                return this;
            }
        },
        attr: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var option;
                if (arguments.length > 0) {
                    option = arguments[0];
                    if (2 === arguments.length) {
                        this.setAttribute(option, arguments[1]);
                    }
                    if ('object' === typeof option) {
                        for (let key in option) {
                            if (option.hasOwnProperty(key)) {
                                this[key] = option[key];
                            }
                        }
                    } else if ('string' === typeof option) {
                        return this.getAttribute(option);
                    }
                }
                return this;
            }
        },
        position: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var obj;
                if (selector) {
                    var ele = this.find(selector);
                    ele.length > 0 ? obj = ele.eq(0) : obj = this;
                } else {
                    obj = this;
                }
                return obj.getBoundingClientRect();
            }
        },
        offset: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var obj;
                if (selector) {
                    var ele = this.find(selector);
                    ele.length > 0 ? obj = ele.eq(0) : obj = this;
                } else {
                    obj = this;
                }
                return {
                    left: obj.offsetLeft,
                    top: obj.offsetTop,
                    parent: obj.offsetParent,
                    width: obj.offsetWidth,
                    height: obj.offsetHeight
                }
            }
        },
        scroll: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var obj;
                if (selector) {
                    var ele = this.find(selector);
                    ele.length > 0 ? obj = ele.eq(0) : obj = this;
                } else {
                    obj = this;
                }
                return {
                    left: obj.scrollLeft,
                    top: obj.scrollTop,
                    width: obj.scrollWidth,
                    height: obj.scrollHeight
                }
            }
        },
        create: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (arguments.length === 0) {
                    return this.appendChild(document.createElement(String(this.tagName).toLowerCase()));
                } else if (arguments.length === 1) {
                    return this.appendChild(document.createElement(arguments[0]));
                } else if (arguments.length === 2) {
                    var node = this.appendChild(document.createElement(arguments[0]));
                    if (typeof arguments[1] === 'object') {
                        for (let key in arguments[1]) {
                            if (arguments[1].hasOwnProperty(key)) {
                                node[key] = arguments[1][key];
                                node.style[key] = arguments[1][key];
                            }
                        }
                    }
                    return node;
                }
            }
        },
        tag: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (arguments.length === 0) {
                    return this.tagName.toLowerCase();
                } else if (arguments.length === 1) {
                    if (this.outerHTML.lastIndexOf('<') === 0) {
                        if (this.outerHTML.indexOf(' ') != -1) {
                            var i = this.outerHTML.indexOf(' ');
                            this.outerHTML = this.outerHTML.replace(this.outerHTML.substring(1, i), arguments[0]);
                        } else {
                            var i = this.outerHTML.length;
                            this.outerHTML = this.outerHTML.replace(this.outerHTML.substring(1, i - 1), arguments[0]);
                        }
                    } else {
                        var i = this.outerHTML.indexOf(' '),
                            j = this.outerHTML.indexOf('>'),
                            k = this.outerHTML.lastIndexOf('/'),
                            l = this.outerHTML.length;
                        if (i < j && i != -1) {
                            this.outerHTML = this.outerHTML.replace(this.outerHTML.substring(1, i), arguments[0]).replace(this.outerHTML.substring(k + 1, l - 1), arguments[0]);
                        } else if (i > j && i != -1 || i === -1) {
                            this.outerHTML = this.outerHTML.replace(this.outerHTML.substring(1, j), arguments[0]).replace(this.outerHTML.substring(k + 1, l - 1), arguments[0]);
                        }
                    }
                    return this;
                }
            }
        },
        val: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (arguments.length === 0) {
                    return this.value;
                } else if (arguments.length === 1) {
                    this.value = arguments[0];
                    return this;
                }
            }
        },
        html: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (arguments.length === 0) {
                    return this.innerHTML;
                } else if (arguments.length === 1) {
                    this.innerHTML = arguments[0];
                    return this;
                }
            }
        },
        text: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (arguments.length === 0) {
                    return this.textContent;
                } else if (arguments.length === 1) {
                    this.textContent = arguments[0];
                    return this;
                }
            }
        },
        wrap: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var i = arguments[0].indexOf('>'),
                    j = arguments[0].lastIndexOf('/');
                this.outerHTML = arguments[0].substring(0, i + 1) + this.outerHTML + arguments[0].substring(j - 1);
                return this;
            }
        },
        unwrap: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(bool) {
                if (this.parentNode) {
                    if (!bool || bool === false) {
                        this.parentNode.outerHTML = this.parentNode.innerHTML;
                    } else {
                        this.parentNode.outerHTML = this.outerHTML;
                    }
                }
                return this;
            }
        },
        append: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (this.hasAttribute('value') === false) {
                    this.innerHTML += arguments[0];
                } else {
                    this.value += arguments[0];
                }
                return this;
            }
        },
        prepend: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (this.hasAttribute('value') === false) {
                    this.innerHTML = arguments[0] + this.innerHTML;
                } else {
                    this.value = arguments[0] + this.value;
                }
                return this;
            }
        },
        insertFront: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (this.parentNode) {
                    this.parentNode.insertBefore(arguments[0], this);
                }
                return this;
            }
        },
        insertBack: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (this.parentNode) {
                    if (nextnode(this)) {
                        this.parentNode.insertBefore(arguments[0], nextnode(this));
                    } else {
                        this.parentNode.appendChild(arguments[0]);
                    }
                }
                return this;
            }
        },
        after: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var obj = $parseHTML(arguments[0]);
                for (let i = 0, len = obj.length; i < len; i++) {
                    this.insertBack(obj[i]);
                }
                return this;
            }
        },
        before: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var obj = $parseHTML(arguments[0]);
                for (let i = 0, len = obj.length; i < len; i++) {
                    this.insertFront(obj[i]);
                }
                return this;
            }
        },
        empty: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                if (selector) {
                    var obj = this.find(selector);
                    for (let i = 0, len = obj.length; i < len; i++) {
                        obj[i].innerHTML = "";
                    }
                } else {
                    this.innerHTML = "";
                }
                return this;
            }
        },
        replace: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(str1, str2, bool) {
                if (!bool || bool === false) {
                    if (this.hasAttribute('value') === false) {
                        this.innerHTML = this.innerHTML.replace(str1, str2);
                    } else {
                        this.value = this.value.replace(str1, str2);
                    }
                } else {
                    if (this.hasAttribute('value') === false) {
                        this.innerHTML = this.innerHTML.replaceAll(str1, str2);
                    } else {
                        this.value = this.value.replaceAll(str1, str2);
                    }
                }
                return this;
            }
        },
        replaceWith: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                this.outerHTML = arguments[0];
                return this;
            }
        },
        remove: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                if (selector) {
                    var obj = this.find(selector);
                    for (let i = 0, len = obj.length; i < len; i++) {
                        obj[i].parentNode.removeChild(obj[i]);
                    }
                    return this;
                } else {
                    return this.parentNode.removeChild(this);
                }
            }
        },
        clear: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(str, bool) {
                if (str) {
                    if (this.innerHTML.indexOf(str) != -1) {
                        if (!bool || bool === false) {
                            this.innerHTML = this.innerHTML.replace(str, '');
                        } else {
                            this.innerHTML = this.innerHTML.replaceAll(str, '');
                        }
                        return this;
                    }
                } else {
                    return this.empty();
                }
            }
        },
        show: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var obj;
                if (selector) {
                    var ele = this.find(selector);
                    ele.length > 0 ? obj = ele.eq(0) : obj = this;
                } else {
                    obj = this;
                }
                if (obj.css('display') === 'none') {
                    if (obj.hasAttribute('data-display') === true) {
                        obj.style.display = obj.dataset.display;
                        delete obj.dataset.display;
                    } else {
                        if (isBlock(obj) === 1) {
                            obj.style.display = 'block';
                        } else {
                            obj.style.display = 'inline';
                        }
                    }
                }
                return this;
            }
        },
        hide: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var obj;
                if (selector) {
                    var ele = this.find(selector);
                    ele.length > 0 ? obj = ele.eq(0) : obj = this;
                } else {
                    obj = this;
                }
                if (obj.css('display') != 'none') {
                    obj.dataset.display = obj.css('display');
                    obj.style.display = 'none';
                }
                return this;
            }
        },
        displayToggle: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var obj;
                if (selector) {
                    var ele = this.find(selector);
                    ele.length > 0 ? obj = ele.eq(0) : obj = this;
                } else {
                    obj = this;
                }
                if (obj.css('display') != 'none') {
                    obj.hide(selector);
                } else {
                    obj.show(selector);
                }
                return this;
            }
        },
        float: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (arguments.length === 1) {
                    this.style.float = arguments[0];
                } else if (arguments.length === 0) {
                    this.style.float = 'left';
                }
                return this;
            }
        },
        display: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (arguments.length === 1) {
                    this.style.display = arguments[0];
                } else if (arguments.length === 0) {
                    if (this.css('display') === 'none') {
                        this.show();
                    }
                }
                return this;
            }
        },
        opacity: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var timer = null;
                timer = setTimeout(function() {
                    this.style.transition = '';
                    clearTimeout(timer);
                }.bind(this), 500);
                if (arguments.length === 0) {
                    this.style.transition = 'opacity 0.5s';
                    this.style.opacity = 0.5;
                    return this;
                } else if (arguments.length === 1) {
                    this.style.transition = 'opacity 0.5s';
                    this.style.opacity = arguments[0];
                    return this;
                }
            }
        },
        colour: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var timer = null;
                timer = setTimeout(function() {
                    this.style.transition = '';
                    clearTimeout(timer);
                }.bind(this), 500);
                this.style.transition = 'background-color 0.5s';
                this.style.backgroundColor = arguments[0];
                return this;
            }
        },
        defaultCSS: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var obj;
                if (selector) {
                    var ele = this.find(selector);
                    ele.length > 0 ? obj = ele.eq(0) : obj = this;
                } else {
                    obj = this;
                }
                if (obj.hasAttribute('style') === true) {
                    obj.removeAttribute('style');
                }
                return this;
            }
        },
        hasClass: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(cName) {
                return !!this.className.match(new RegExp("(\\s|^)" + cName + "(\\s|$)"));
            }
        },
        addClass: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(cName) {
                if (!this.hasClass(cName)) {
                    this.className += " " + cName;
                }
                return this;
            }
        },
        removeClass: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(cName) {
                if (this.hasClass(cName)) {
                    this.className = this.className.replace(new RegExp("(\\s|^)" + cName + "(\\s|$)"), " ");
                }
                return this;
            }
        },
        toggleClass: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(cName) {
                var arr = cName.split(' ');
                for (let i = 0; i < arr.length; i++) {
                    var reg = new RegExp('\\b' + arr[i] + '\\b');
                    if (reg.test(this.className)) {
                        var className = this.className.split(' ');
                        for (let j = 0; j < className.length; j++) {
                            if (reg.test(className[j])) {
                                className.splice(j, 1);
                            }
                        }
                        this.className = className.join(' ');
                    } else {
                        this.className ? this.className += ' ' + arr[i] : this.className += arr[i];
                    }
                }
                return this;
            }
        },
        index: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(obj) {
                if (obj) {
                    return $index(this, obj);
                } else {
                    return $make(this.parentNode.children).indexOf(this);
                }
            }
        },
        find: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var nodez = [],
                    nodes = this.getElementsByTagName('*');
                for (let i = 0, len = nodes.length; i < len; i++) {
                    if ($matches(nodes[i], selector) === true) {
                        nodez.push(nodes[i]);
                    }
                }
                if (nodez.length > 0) {
                    return nodez;
                } else {
                    return this;
                }
            }
        },
        contains: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.compareDocumentPosition(arguments[0]) - 19 > 0;
            }
        },
        siblings: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var nodes = [],
                    previ = prenode(this);
                while (previ) {
                    if (previ.nodeType === 1) {
                        nodes.push(previ);
                    }
                    previ = prenode(previ);
                }
                nodes.reverse();
                var nexts = nextnode(this);
                while (nexts) {
                    if (nexts.nodeType === 1) {
                        nodes.push(nexts);
                    }
                    nexts = nextnode(nexts);
                }
                if (selector) {
                    var nodez = [];
                    for (let i = 0, len = nodes.length; i < len; i++) {
                        if ($matches(nodes[i], selector) === true) {
                            nodez.push(nodes[i]);
                        }
                    }
                    if (nodez.length > 0) {
                        return nodez;
                    } else {
                        return nodes;
                    }
                } else {
                    return nodes;
                }
            }
        },
        child: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var objChild = [],
                    objs = this.getElementsByTagName('*');
                for (let i = 0, j = objs.length; i < j; ++i) {
                    if (objs[i].nodeType != 1) {
                        alert(objs[i].nodeType);
                        continue;
                    }
                    var temp = objs[i].parentNode;
                    if (temp.nodeType === 1) {
                        if (temp === this) {
                            objChild[objChild.length] = objs[i];
                        }
                    } else if (temp.parentNode === this) {
                        objChild[objChild.length] = objs[i];
                    }
                }
                if (selector) {
                    var nodes = [];
                    for (let i = 0, len = objChild.length; i < len; i++) {
                        if ($matches(objChild[i], selector) === true) {
                            nodes.push(objChild[i]);
                        }
                    }
                    if (nodes.length > 0) {
                        return nodes;
                    } else {
                        return objChild;
                    }
                } else {
                    return objChild;
                }
            }
        },
        clone: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (arguments.length === 0) {
                    return this.cloneNode(true);
                } else if (arguments.length === 1) {
                    return this.cloneNode(arguments[0]);
                }
            }
        },
        parent: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                if (this.parentNode) {
                    if (selector) {
                        var nodez = [],
                            nodes = this.parent().parent().child();
                        for (let i = 0, len = nodes.length; i < len; i++) {
                            if ($matches(nodes[i], selector) === true) {
                                nodez.push(nodes[i]);
                            }
                        }
                        if (nodez.length > 0) {
                            return nodez;
                        } else {
                            return this.parentNode;
                        }
                    } else {
                        return this.parentNode;
                    }
                } else {
                    return this;
                }
            }
        },
        parents: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                if (this.parentNode.parentNode) {
                    if (selector) {
                        return this.parent().parent(selector);
                    } else {
                        return this.parent().parent();
                    }
                } else {
                    if (this.parentNode) {
                        if (selector) {
                            return this.parent(selector);
                        } else {
                            return this.parent();
                        }
                    } else {
                        return this;
                    }
                }
            }
        },
        prev: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                if (!prenode(this)) {
                    return this;
                } else {
                    if (selector) {
                        var nodes = this.prevAll(),
                            nodez = [];
                        for (let i = 0, len = nodes.length; i < len; i++) {
                            if ($matches(nodes[i], selector) === true) {
                                nodez.push(nodes[i]);
                            }
                        }
                        if (nodez.length > 0) {
                            return nodez[nodez.length - 1];
                        } else {
                            return prenode(this);
                        }
                    } else {
                        return prenode(this);
                    }
                }
            }
        },
        next: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                if (!nextnode(this)) {
                    return this;
                } else {
                    if (selector) {
                        var nodes = this.nextAll(),
                            nodez = [];
                        for (let i = 0, len = nodes.length; i < len; i++) {
                            if ($matches(nodes[i], selector) === true) {
                                nodez.push(nodes[i]);
                            }
                        }
                        if (nodez.length > 0) {
                            return nodez[0];
                        } else {
                            return nextnode(this);
                        }
                    } else {
                        return nextnode(this);
                    }
                }
            }
        },
        prevAll: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var nodes = [],
                    previ = prenode(this);
                while (previ) {
                    if (previ.nodeType === 1) {
                        nodes.push(previ);
                    }
                    previ = prenode(previ);
                }
                nodes.reverse();
                if (selector) {
                    var nodez = [];
                    for (let i = 0, len = nodes.length; i < len; i++) {
                        if ($matches(nodes[i], selector) === true) {
                            nodez.push(nodes[i]);
                        }
                    }
                    if (nodez.length > 0) {
                        return nodez;
                    } else {
                        return nodes;
                    }
                } else {
                    return nodes;
                }
            }
        },
        nextAll: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var nodes = [],
                    nexts = nextnode(this);
                while (nexts) {
                    if (nexts.nodeType === 1) {
                        nodes.push(nexts);
                    }
                    nexts = nextnode(nexts);
                }
                if (selector) {
                    var nodez = [];
                    for (let i = 0, len = nodes.length; i < len; i++) {
                        if ($matches(nodes[i], selector) === true) {
                            nodez.push(nodes[i]);
                        }
                    }
                    if (nodez.length > 0) {
                        return nodez;
                    } else {
                        return nodes;
                    }
                } else {
                    return nodes;
                }
            }
        },
        first: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                if (this.hasChildNodes()) {
                    if (selector) {
                        var nodez = [],
                            nodes = this.child();
                        for (let i = 0, len = nodes.length; i < len; i++) {
                            if ($matches(nodes[i], selector) === true) {
                                nodez.push(nodes[i]);
                            }
                        }
                        if (nodez.length > 0) {
                            return nodez[0];
                        } else {
                            return firstnode(this);
                        }
                    } else {
                        return firstnode(this);
                    }
                } else {
                    return this;
                }
            }
        },
        last: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                if (this.hasChildNodes()) {
                    if (selector) {
                        var nodez = [],
                            nodes = this.child();
                        for (let i = 0, len = nodes.length; i < len; i++) {
                            if ($matches(nodes[i], selector) === true) {
                                nodez.push(nodes[i]);
                            }
                        }
                        if (nodez.length > 0) {
                            return nodez[nodez.length - 1];
                        } else {
                            return lastnode(this);
                        }
                    } else {
                        return lastnode(this);
                    }
                } else {
                    return this;
                }
            }
        },
        posterity: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                if (this.hasChildNodes()) {
                    if (selector) {
                        var nodez = [],
                            nodes = $make(this.getElementsByTagName('*'));
                        for (let i = 0, len = nodes.length; i < len; i++) {
                            if ($matches(nodes[i], selector) === true) {
                                nodez.push(nodes[i]);
                            }
                        }
                        if (nodez.length > 0) {
                            return nodez;
                        } else {
                            return $make(this.getElementsByTagName('*'));
                        }
                    } else {
                        return $make(this.getElementsByTagName('*'));
                    }
                } else {
                    return this;
                }
            }
        },
        closest: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var el = this;
                while (el) {
                    if (matchesElement(el, arguments[0])) {
                        break;
                    }
                    el = el.parentNode;
                }
                return el;
            }
        },
        lock: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var obj;
                if (selector) {
                    var ele = this.find(selector);
                    ele.length > 0 ? obj = ele.eq(0) : obj = this;
                } else {
                    obj = this;
                }
                if (obj.css('pointer-events') != 'none') {
                    obj.css('pointer-events', 'none');
                }
                return this;
            }
        },
        unlock: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(selector) {
                var obj;
                if (selector) {
                    var ele = this.find(selector);
                    ele.length > 0 ? obj = ele.eq(0) : obj = this;
                } else {
                    obj = this;
                }
                if (obj.css('pointer-events') === 'none') {
                    if (obj.hasAttribute('style') === true && String(obj.getAttribute('style')).indexOf('pointer-events: none;') != -1) {
                        obj.css('pointer-events', '');
                    } else {
                        obj.css('pointer-events', 'auto');
                    }
                }
                return this;
            }
        },
        slideDown: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (this.css('display') === 'none') {
                    var that = this,
                        timer = null,
                        speed,
                        heightId = Math.random() * 2,
                        i = 0,
                        h = parseInt(this.css('height'));
                    cancelAnimationFrame(timer);
                    if (h === 0) {
                        var nodes = this.children;
                        for (let i = 0, len = nodes.length; i < len; i++) {
                            if (nodes[i].css('display') === 'block') {
                                h += nodes[i].offsetHeight;
                            }
                        }
                    }
                    this.show();
                    newStorage[heightId] = h;
                    this.style.height = 0;
                    this.style.overflow = 'hidden';
                    if (arguments.length > 0) {
                        speed = arguments[0];
                        if (speed === 'fast') {
                            speed = 10;
                        } else if (speed === 'normal') {
                            speed = 4;
                        } else if (speed === 'slow') {
                            speed = 0.5;
                        }
                    } else {
                        speed = 4;
                    }

                    function goSlideDown() {
                        timer = requestAnimationFrame(goSlideDown);
                        i += speed;
                        that.style.height = i++ + 'px';
                        if (i >= newStorage[heightId]) {
                            that.style.overflow = '';
                            that.style.height = newStorage[heightId] + 'px';
                            delete newStorage[heightId];
                            cancelAnimationFrame(timer);
                            timer = null;
                        }
                    }
                    timer = requestAnimationFrame(goSlideDown);
                }
                return this;
            }
        },
        slideUp: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (this.css('display') != 'none') {
                    var that = this,
                        timer = null,
                        speed,
                        heightId = Math.random() * 2,
                        i = parseInt(this.css('height'));
                    cancelAnimationFrame(timer);
                    if (i === 0) {
                        var nodes = this.children;
                        for (let i = 0, len = nodes.length; i < len; i++) {
                            if (nodes[i].css('display') === 'block') {
                                i += nodes[i].offsetHeight;
                            }
                        }
                    }
                    this.show();
                    newStorage[heightId] = i;
                    this.style.height = i + 'px';
                    this.style.overflow = 'hidden';
                    if (arguments.length > 0) {
                        speed = arguments[0];
                        if (speed === 'fast') {
                            speed = 10;
                        } else if (speed === 'normal') {
                            speed = 4;
                        } else if (speed === 'slow') {
                            speed = 1;
                        }
                    } else {
                        speed = 4;
                    }

                    function goSlideUp() {
                        timer = requestAnimationFrame(goSlideUp);
                        i -= speed;
                        that.style.height = i + 'px';
                        if (i <= 0) {
                            that.style.overflow = '';
                            that.hide();
                            that.style.height = newStorage[heightId] + 'px';
                            delete newStorage[heightId];
                            cancelAnimationFrame(timer);
                            timer = null;
                        }
                    }
                    timer = requestAnimationFrame(goSlideUp);
                }
                return this;
            }
        },
        slideToggle: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (this.css('display') != 'none') {
                    arguments.length === 0 ? this.slideUp() : this.slideUp(arguments[0]);
                } else {
                    arguments.length === 0 ? this.slideDown() : this.slideDown(arguments[0]);
                }
                return this;
            }
        },
        animate: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(json, duration, timing, fn) {
                var timer = null;
                if (duration === 'fast') {
                    duration = 0.5;
                } else if (duration === 'normal') {
                    duration = 1;
                } else if (duration === 'slow') {
                    duration = 2;
                }
                if (json && typeof json === 'object') {
                    for (let key in json) {
                        if (json.hasOwnProperty(key)) {
                            this.style[key] = json[key];
                            this.style.transitionProperty = 'all';
                            this.style.transitionDuration = duration + 's';
                            this.style.transitionTimingFunction = timing;
                            this.style.transitionDelay = 0;
                        }
                    }
                }
                timer = setTimeout(function() {
                    this.style.transitionProperty = '';
                    this.style.transitionDuration = '';
                    this.style.transitionTimingFunction = '';
                    this.style.transitionDelay = '';
                    if (fn && typeof fn === 'function') {
                        fn.apply(this, arguments);
                    }
                    clearTimeout(timer);
                }.bind(this), duration * 1000);
                return this;
            }
        },
        drag: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(str) {
                drag(this, str);

                function drag(elem, str) {
                    elem.onmousedown = function(ev) {
                        var ev = ev || window.event,
                            disX = ev.clientX - this.offsetLeft,
                            disY = ev.clientY - this.offsetTop;
                        elem.style.position = 'absolute';
                        elem.style.cursor = 'pointer';
                        if (elem.setCapture) {
                            elem.setCapture();
                        }
                        document.onmousemove = function(ev) {
                            var ev = ev || window.event,
                                L = ev.clientX - disX,
                                T = ev.clientY - disY;
                            if (str === 'left') {
                                elem.style.left = L + 'px';
                            } else if (str === 'top') {
                                elem.style.top = T + 'px';
                            } else if (typeof str === 'object') {
                                if (L < 0) {
                                    L = 0;
                                } else if (L > str.offsetWidth - elem.offsetWidth) {
                                    L = str.offsetWidth - elem.offsetWidth;
                                }
                                if (T < 0) {
                                    T = 0;
                                } else if (T > str.offsetHeight - elem.offsetHeight) {
                                    T = str.offsetHeight - elem.offsetHeight;
                                }
                                elem.style.left = L + 'px';
                                elem.style.top = T + 'px';
                            } else if (!str || str === false) {
                                if (L < 0) {
                                    L = 0;
                                } else if (L > document.documentElement.scrollWidth - elem.offsetWidth) {
                                    L = document.documentElement.scrollWidth - elem.offsetWidth;
                                }
                                if (T < 0) {
                                    T = 0;
                                } else if (T > document.documentElement.scrollHeight - elem.offsetHeight) {
                                    T = document.documentElement.scrollHeight - elem.offsetHeight;
                                }
                                elem.style.left = L + 'px';
                                elem.style.top = T + 'px';
                            } else if (str === true) {
                                elem.style.left = L + 'px';
                                elem.style.top = T + 'px';
                            }
                        }
                        document.onmouseup = function() {
                            document.onmousemove = null;
                            document.onmouseup = null;
                            if (elem.releaseCapture) {
                                elem.releaseCapture();
                            }
                        }
                        return false;
                    }
                }
                return this;
            }
        },
        fadeOut: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(speed) {
                if (this.css('display') != 'none') {
                    this.show();
                    fadeOut(this, speed);
                }

                function fadeOut(elem, speed) {
                    var tempOpacity = 1;
                    (function() {
                        if (speed === 'fast') {
                            speed = 1;
                        } else if (speed === 'normal') {
                            speed = 10;
                        } else if (speed === 'slow') {
                            speed = 20;
                        }
                        setOpacity(elem, tempOpacity);
                        tempOpacity -= 0.05;
                        if (tempOpacity > 0) {
                            setTimeout(arguments.callee, speed);
                        } else {
                            elem.hide();
                        }
                    })();
                }
                return this;
            }
        },
        fadeIn: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(speed) {
                if (this.css('display') === 'none') {
                    this.show();
                    fadeIn(this, speed);
                }

                function fadeIn(elem, speed) {
                    setOpacity(elem, 0);
                    var tempOpacity = 0;
                    (function() {
                        if (speed === 'fast') {
                            speed = 1;
                        } else if (speed === 'normal') {
                            speed = 10;
                        } else if (speed === 'slow') {
                            speed = 20;
                        }
                        setOpacity(elem, tempOpacity);
                        tempOpacity += 0.05;
                        if (tempOpacity <= 1) {
                            setTimeout(arguments.callee, speed);
                        }
                    })();
                }
                return this;
            }
        },
        fadeTo: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(speed, opacity) {
                this.show();
                fadeTo(this, speed, opacity);

                function fadeTo(elem, speed, opacity) {
                    var tempOpacity = 0;
                    (function() {
                        if (speed === 'fast') {
                            speed = 1;
                        } else if (speed === 'normal') {
                            speed = 10;
                        } else if (speed === 'slow') {
                            speed = 20;
                        }
                        setOpacity(elem, tempOpacity);
                        tempOpacity += 0.05;
                        if (tempOpacity <= opacity) {
                            setTimeout(arguments.callee, speed);
                        }
                    })();
                }
                return this;
            }
        },
        fadeToggle: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                if (this.css('display') != 'none') {
                    arguments.length === 0 ? this.fadeOut() : this.fadeOut(arguments[0]);
                } else {
                    arguments.length === 0 ? this.fadeIn() : this.fadeIn(arguments[0]);
                }
                return this;
            }
        }
    });
    (function() {
        document.on = window.on = $.fn.on;
        document.off = window.off = $.fn.off;
        document.go = window.go = $.fn.go;
        document.stop = window.stop = $.fn.stop;
        document.delegate = window.delegate = $.fn.delegate;
        allEvents.replace(/\w+/g, function(ev) {
            document['$' + ev] = window['$' + ev] = $.fn['$' + ev] = function(fn) {
                $on(this, ev, fn);
                return this;
            };
        });
        document.wide = function() {
            return $scrollWidth();
        };
        document.high = function() {
            return $scrollHeight();
        };
        window.wide = function() {
            return $clientWidth();
        };
        window.high = function() {
            return $clientHeight();
        };
    })();
    $.add($.dt, {
        format: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(formatStr) {
                var str = formatStr,
                    Week = ['日', '一', '二', '三', '四', '五', '六'];
                str = str.replace(/yyyy|YYYY/, this.getFullYear());
                str = str.replace(/yy|YY/, (this.getYear() % 100) > 9 ? (this.getYear() % 100).toString() : '0' + (this.getYear() % 100));
                str = str.replace(/MM/, (this.getMonth() + 1) > 9 ? (this.getMonth() + 1).toString() : '0' + (this.getMonth() + 1));
                str = str.replace(/M/g, (this.getMonth() + 1));
                str = str.replace(/w|W/g, Week[this.getDay()]);
                str = str.replace(/dd|DD/, this.getDate() > 9 ? this.getDate().toString() : '0' + this.getDate());
                str = str.replace(/d|D/g, this.getDate());
                str = str.replace(/hh|HH/, this.getHours() > 9 ? this.getHours().toString() : '0' + this.getHours());
                str = str.replace(/h|H/g, this.getHours());
                str = str.replace(/mm/, this.getMinutes() > 9 ? this.getMinutes().toString() : '0' + this.getMinutes());
                str = str.replace(/m/g, this.getMinutes());
                str = str.replace(/ss|SS/, this.getSeconds() > 9 ? this.getSeconds().toString() : '0' + this.getSeconds());
                str = str.replace(/s|S/g, this.getSeconds());
                return str;
            }
        },
        addDate: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(type, num) {
                var type = type.toLowerCase();
                switch (type) {
                    case 's':
                        return new Date.parse(Date.parse(this) + (1000 * num));
                    case 'i':
                        return new Date.parse(Date.parse(this) + (60000 * num));
                    case 'h':
                        return new Date(Date.parse(this) + (3600000 * num));
                    case 'd':
                        return new Date(Date.parse(this) + (86400000 * num));
                    case 'w':
                        return new Date(Date.parse(this) + ((86400000 * 7) * num));
                    case 'm':
                        return new Date(this.getFullYear(), (this.getMonth()) + num, this.getDate(), this.getHours(), this.getMinutes(), this.getSeconds());
                    case 'q':
                        return new Date(this.getFullYear(), (this.getMonth()) + num * 3, this.getDate(), this.getHours(), this.getMinutes(), this.getSeconds());
                    case 'y':
                        return new Date((this.getFullYear() + num), this.getMonth(), this.getDate(), this.getHours(), this.getMinutes(), this.getSeconds());
                }
            }
        },
        dateDiff: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(type, date) {
                if (typeof date === 'string') date = date.toDate();
                switch (type) {
                    case 's':
                        return parseInt((date - this) / 1000);
                    case 'i':
                        return parseInt((date - this) / 60000);
                    case 'h':
                        return parseInt((date - this) / 3600000);
                    case 'd':
                        return parseInt((date - this) / 86400000);
                    case 'w':
                        return parseInt((date - this) / (86400000 * 7));
                    case 'm':
                        return (date.getMonth() + 1) + ((date.getFullYear() - this.getFullYear()) * 12) - (this.getMonth() + 1);
                    case 'y':
                        return date.getFullYear() - this.getFullYear();
                }
            }
        }
    });
    $.add($.st, {
        leftTrim: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.replace(/(^\s*)/g, "");
            }
        },
        rightTrim: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.replace(/(\s*$)/g, "");
            }
        },
        trimAll: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.replace(/\s/g, "");
            }
        },
        replaceAll: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(s1, s2) {
                return this.replace(new RegExp(s1, "gm"), s2);
            }
        },
        firstUpperCase: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.toLowerCase().replace(/\b[a-z]/g, function(s) {
                    return s.toUpperCase();
                });
            }
        },
        startWith: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(s) {
                if (s === null || s === "" || this.length === 0 || s.length > this.length)
                    return false;
                if (this.substr(0, s.length) === s)
                    return true;
                else
                    return false;
                return true;
            }
        },
        endWith: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(s) {
                if (s === null || s === "" || this.length === 0 || s.length > this.length)
                    return false;
                if (this.substring(this.length - s.length) === s)
                    return true;
                else
                    return false;
                return true;
            }
        },
        append: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(aStr) {
                return this.concat(aStr);
            }
        },
        prepend: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(aStr) {
                return aStr + this;
            }
        },
        appendTo: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(obj) {
                if (obj.hasAttribute('value') === false) {
                    return obj.innerHTML += this;
                } else {
                    return obj.value += this;
                }
            }
        },
        prependTo: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(obj) {
                if (obj.hasAttribute('value') === false) {
                    return obj.innerHTML = this + obj.innerHTML;
                } else {
                    return obj.value = this + obj.value;
                }
            }
        },
        insert: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(ofset, aStr) {
                if (ofset < 0 || ofset >= this.length - 1) {
                    return this.append(aStr);
                }
                return this.substring(0, ofset + 1) + aStr + this.substring(ofset + 1);
            }
        },
        insertStrPerIndex: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(index, str) {
                if (this.length > index && index > 0) {
                    var arr = new Array(),
                        num = parseInt(this.length / index);
                    console.log(num);
                    for (let i = 0; i <= num; i++) {
                        var firstval = i * index;
                        if (firstval < this.length) {
                            arr.push(this.substr(firstval, index));
                        }
                    }
                    return arr.join(str);
                } else {
                    return this.toString();
                }
            }
        },
        left: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(n) {
                return this.slice(0, n - this.slice(0, n).replace(/[\x00-\xff]/g, "").length);
            }
        },
        right: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(n) {
                return this.slice(this.slice(-n).replace(/[\x00-\xff]/g, "").length - n);
            }
        },
        setCharAt: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(sIndex, aStr) {
                if (sIndex < 0 || sIndex > this.length - 1) {
                    return this.valueOf();
                }
                return this.substring(0, sIndex) + aStr + this.substring(sIndex + 1);
            }
        },
        deleteCharAt: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(sIndex) {
                if (sIndex < 0 || sIndex >= this.length) {
                    return this.valueOf();
                } else if (sIndex === 0) {
                    return this.substring(1, this.length);
                } else if (sIndex === this.length - 1) {
                    return this.substring(0, this.length - 1);
                } else {
                    return this.substring(0, sIndex) + this.substring(sIndex + 1);
                }
            }
        },
        deleteString: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(sIndex, eIndex) {
                if (sIndex === eIndex) {
                    return this.deleteCharAt(sIndex);
                } else {
                    if (sIndex > eIndex) {
                        var tIndex = eIndex;
                        eIndex = sIndex;
                        sIndex = tIndex;
                    }
                    if (sIndex < 0) sIndex = 0;
                    if (eIndex > this.length - 1) eIndex = this.length - 1;
                    return this.substring(0, sIndex + 1) + this.substring(eIndex, this.length);
                }
            }
        },
        cutString: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(cutLength) {
                if (!cutLength) {
                    cutLength = this.countLength();
                }
                var strLength = 0,
                    cutStr = "";
                if (cutLength > this.countLength()) {
                    cutStr = this;
                } else {
                    for (let i = 0; i < this.length; i++) {
                        if (this.charAt(i) > '~') {
                            strLength += 2;
                        } else {
                            strLength += 1;
                        }
                        if (strLength >= cutLength) {
                            cutStr = this.substring(0, i + 1);
                            break;
                        }
                    }
                }
                return cutStr;
            }
        },
        countLength: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var len = 0;
                for (let i = 0; i < this.length; i++) {
                    if (this.charCodeAt(i) > 255)
                        len += 2;
                    else
                        len++;
                }
                return len;
            }
        },
        total: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(re) {
                re = eval("/" + re + "/ig");
                return this.match(re).length;
            }
        },
        reverse: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.split('').reverse().join('');
            }
        },
        regular: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(reg) {
                var result = true;
                if (this.length > 0) {
                    if (!reg.test(this)) {
                        result = false;
                    }
                }
                return result;
            }
        },
        isNull: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.trim().length === 0 ? true : false;
            }
        },
        isNumber: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                for (let i = 0; i < this.length; i++) {
                    if (this.charAt(i) < '0' || this.charAt(i) > '9') {
                        return false;
                    }
                }
                return true;
            }
        },
        isVersion: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var reg = /^([a-zA-Z_])([a-zA-Z0-9_.])*$/;
                return this.regular(reg);
            }
        },
        isString: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var reg = /^[^']*$/;
                return this.regular(reg);
            }
        },
        isLetter: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var reg = /^[a-zA-Z]+$/;
                return this.regular(reg);
            }
        },
        equals: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(aStr) {
                if (this.length != aStr.length) {
                    return false;
                } else {
                    for (let i = 0; i < this.length; i++) {
                        if (this.charAt(i) != aStr.charAt(i)) {
                            return false;
                        }
                    }
                    return true;
                }
            }
        },
        equalsIgnoreCase: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(aStr) {
                if (this.length != aStr.length) {
                    return false;
                } else {
                    var tmp1 = this.toLowerCase(),
                        tmp2 = aStr.toLowerCase();
                    return tmp1.equals(tmp2);
                }
            }
        },
        camelize: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var re = /-(\w)/g;
                return this.replace(re, function() {
                    var args = arguments;
                    return args[1].toUpperCase();
                });
            }
        },
        uncamelize: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var re = /([a-z])([A-Z])/g;
                return this.replace(re, function() {
                    var args = arguments;
                    return args[1] + "-" + args[2].toLowerCase();
                });
            }
        },
        toArray: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var arr = [];
                for (let x = 0; x < this.length; x++) {
                    arr[x] = this.charAt(x);
                }
                return arr;
            }
        },
        toDate: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var converted = Date.parse(this),
                    myDate = new Date(converted);
                if (isNaN(myDate)) {
                    var arys = this.split('-');
                    myDate = new Date(arys[0], --arys[1], arys[2]);
                }
                return myDate;
            }
        },
        htmlEncode: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<').replace(/>/g, '>');
            }
        },
        htmlDecode: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.replace(/&/g, '&').replace(/"/g, '\"').replace(/</g, '<').replace(/>/g, '>');
            }
        },
        getQuery: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(name) {
                var reg = new RegExp('(^|&)' + name + ' = ([^&] * )(&|$)'),
                    r = this.substr(this.indexOf('/?') + 1).match(reg);
                return r[2] ? unescape(r[2]) : null;
            }
        },
        pad: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(input, length, type) {
                if (!input) return this;
                if (!length || length < 1) var length = 1;
                var input = Array(length + 1).join(input),
                    value,
                    type = type ? type.toUpperCase() : '';
                switch (type) {
                    case 'LEFT':
                        return input + this;
                    case 'BOTH':
                        return input + this + input;
                    default:
                        return this + input;
                }
            }
        }
    });
    $.add($.ar, {
        insert: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(index, item) {
                this.splice(index, 0, item);
                return this;
            }
        },
        pushAll: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var currentLength = this.length;
                for (let i = 0; i < arguments.length; i++) {
                    this[currentLength + i] = arguments[i];
                }
                return this;
            }
        },
        unique: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                this.sort();
                var re = [this[0]];
                for (let i = 1; i < this.length; i++) {
                    if (this[i] !== re[re.length - 1]) {
                        re.push(this[i]);
                    }
                }
                return re;
            }
        },
        indexOf: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(val) {
                for (let i = 0; i < this.length; i++) {
                    if (this[i] === val) return i;
                }
                return -1;
            }
        },
        getMax: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.sortNum(1)[0];
            }
        },
        getMin: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.sortNum(0)[0];
            }
        },
        contains: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(obj) {
                var i = this.length;
                while (i--) {
                    if (this[i] === obj) {
                        return true;
                    }
                }
                return false;
            }
        },
        total: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(o) {
                var t = 0;
                for (let i = 0; i < this.length; i++) {
                    if (this[i] === o) {
                        t++;
                    }
                }
                return t;
            }
        },
        toString: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.join(arguments[0] || "");
            }
        },
        sortNum: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(i) {
                if (!i) {
                    i = 0;
                }
                if (i === 1) {
                    return this.sort(function(a, b) {
                        return b - a;
                    });
                }
                return this.sort(function(a, b) {
                    return a - b;
                });
            }
        },
        random: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                var tempArr = [],
                    me = this,
                    t;
                while (me.length > 0) {
                    t = Math.floor(Math.random() * me.length);
                    tempArr[tempArr.length] = me[t];
                    me = me.removeAt(t);
                }
                return tempArr;
            }
        },
        orderRandom: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                return this.sort(function() {
                    return Math.random() > 0.5 ? "-1" : "1";
                });
            }
        },
        clear: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function() {
                this.splice(0, this.length);
                return this;
            }
        },
        remove: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(val) {
                var index = this.indexOf(val);
                while (index > -1) {
                    this.splice(index, 1);
                    index = this.indexOf(val);
                }
                return this;
            }
        },
        removeAt: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(index) {
                if (index < 0) {
                    return this;
                }
                return this.slice(0, index).concat(this.slice(index + 1, this.length));
            }
        },
        union: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(a) {
                return this.concat(a).unique();
            }
        },
        minus: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(a) {
                var result = [],
                    clone = this;
                for (let i = 0; i < clone.length; i++) {
                    var flag = true;
                    for (let j = 0; j < a.length; j++) {
                        if (clone[i] === a[j])
                            flag = false;
                    }
                    if (flag)
                        result.push(clone[i]);
                }
                return result.unique();
            }
        },
        intersect: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(b) {
                var result = [],
                    a = this;
                for (let i = 0; i < b.length; i++) {
                    var temp = b[i];
                    for (let j = 0; j < a.length; j++) {
                        if (temp === a[j]) {
                            result.push(temp);
                            break;
                        }
                    }
                }
                return result.unique();
            }
        },
        eq: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(index) {
                return this[index];
            }
        },
        each: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(fn) {
                return $each(this, fn);
            }
        }
    });
    $.add($.fx, {
        construct: {
            writable: true,
            enumerable: false,
            configurable: true,
            value: function(aArgs) {
                var oNew = Object.create(this.prototype);
                this.apply(oNew, aArgs);
                return oNew;
            }
        }
    });

    function setScript() {
        var Script = document.getElementsByTagName('script'),
            Head = document.getElementsByTagName('head')[0],
            Style = document.getElementsByTagName('style'),
            Title = document.getElementsByTagName('title')[0],
            Meta = document.getElementsByTagName('meta'),
            Meta1 = document.createElement('meta'),
            Meta2 = document.createElement('meta');
        for (let i = 0, len = Script.length; i < len; i++) {
            if (Script[i].hasAttribute('src') === true && String(Script[i].src).indexOf('Zendollarjs') != -1) {
                Script[i].setAttribute('async', 'async');
            }
        }
        Meta1.setAttribute("http.equiv", "x-ua-compatible");
        Meta1.content = "ie=edge";
        Meta2.name = "viewport";
        Meta2.content = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no";
        if (Meta.length === 1) {
            Head.insertBefore(Meta1, Title);
            Head.insertBefore(Meta2, Title);
        }
        if (Style.length === 0) {
            var aStyle = document.createElement('style');
            Head.appendChild(aStyle);
        }
    }

    function include(path) {
        var a = document.createElement("script");
        a.type = "text/javascript";
        a.src = path;
        var Script = document.getElementsByTagName("script");
        for (let i = 0, len = Script.length; i < len; i++) {
            if (Script[i].hasAttribute('src') === false) {
                document.body.insertBefore(a, Script[i]);
                a.setAttribute('async', 'async');
            } else {
                document.body.appendChild(a);
                a.setAttribute('async', 'async');
            }
        }
    }

    function addLink(path) {
        var h = document.getElementsByTagName('head')[0],
            l = document.getElementsByTagName('link'),
            r = document.createElement('link'),
            s = document.getElementsByTagName('style')[0];
        r.href = path;
        r.rel = "stylesheet";
        if (l.length > 0) {
            h.insertBefore(r, l[0]);
        } else {
            h.insertBefore(r, s);
        }
    }

    function getFuncName(fn) {
        if (!fn) return null;
        var reg = /\bfunction\s+([^(]+)/,
            result = fn.toString().match(reg);
        return result ? result[1] : null;
    }

    function matchesElement(element, selector) {
        if (element.matches) {
            return element.matches(selector);
        } else if (element.matchesSelector) {
            return element.matchesSelector(selector);
        } else if (element.webkitMatchesSelector) {
            return element.webkitMatchesSelector(selector);
        } else if (element.msMatchesSelector) {
            return element.msMatchesSelector(selector);
        } else if (element.mozMatchesSelector) {
            return element.mozMatchesSelector(selector);
        } else if (element.oMatchesSelector) {
            return element.oMatchesSelector(selector);
        }
    }

    function fnW(str) {
        var num;
        str > 10 ? num = str : num = "0" + str;
        return num;
    }

    function GetDateDiff(startTime, endTime, diffType) {
        startTime = startTime.replace(/\-/g, "/");
        endTime = endTime.replace(/\-/g, "/");
        diffType = diffType.toLowerCase();
        var sTime = new Date(startTime),
            eTime = new Date(endTime),
            divNum = 1;
        switch (diffType) {
            case "second":
                divNum = 1000;
                break;
            case "minute":
                divNum = 1000 * 60;
                break;
            case "hour":
                divNum = 1000 * 3600;
                break;
            case "day":
                divNum = 1000 * 3600 * 24;
                break;
            default:
                break;
        }
        return parseInt((eTime.getTime() - sTime.getTime()) / parseInt(divNum));
    }

    function getScrollTop() {
        var scrollTop = 0,
            bodyScrollTop = 0,
            documentScrollTop = 0;
        if (document.body) {
            bodyScrollTop = document.body.scrollTop;
        }
        if (document.documentElement) {
            documentScrollTop = document.documentElement.scrollTop;
        }
        scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop;
        return scrollTop;
    }

    function getScrollHeight() {
        var scrollHeight = 0,
            bodyScrollHeight = 0,
            documentScrollHeight = 0;
        if (document.body) {
            bodyScrollHeight = document.body.scrollHeight;
        }
        if (document.documentElement) {
            documentScrollHeight = document.documentElement.scrollHeight;
        }
        scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight;
        return scrollHeight;
    }

    function getWindowHeight() {
        var windowHeight = 0;
        if (document.compatMode === "CSS1Compat") {
            windowHeight = document.documentElement.clientHeight;
        } else {
            windowHeight = document.body.clientHeight;
        }
        return windowHeight;
    }

    function Observer(data) {
        this.data = data;
        this.walk(data);
    }
    Observer.prototype = {
        walk: function(data) {
            var self = this;
            Object.keys(data).forEach(function(key) {
                self.defineReactive(data, key, data[key]);
            });
        },
        defineReactive: function(data, key, val) {
            var dep = new Dep(),
                childObj = observe(val);
            Object.defineProperty(data, key, {
                enumerable: true,
                configurable: true,
                get: function getter() {
                    if (Dep.target) {
                        dep.addSub(Dep.target);
                    }
                    return val;
                },
                set: function setter(newVal) {
                    if (newVal === val) {
                        return;
                    }
                    val = newVal;
                    dep.notify();
                }
            });
        }
    };

    function observe(value, vm) {
        if (!value || typeof value !== 'object') {
            return;
        }
        return new Observer(value);
    }

    function Dep() {
        this.subs = [];
    }
    Dep.prototype = {
        addSub: function(sub) {
            this.subs.push(sub);
        },
        notify: function() {
            this.subs.forEach(function(sub) {
                sub.update();
            });
        }
    };
    Dep.target = null;

    function Watcher(vm, exp, cb) {
        this.cb = cb;
        this.vm = vm;
        this.exp = exp;
        this.value = this.get();
    }
    Watcher.prototype = {
        update: function() {
            this.run();
        },
        run: function() {
            var value = this.vm.data[this.exp],
                oldVal = this.value;
            if (value !== oldVal) {
                this.value = value;
                this.cb.call(this.vm, value, oldVal);
            }
        },
        get: function() {
            Dep.target = this;
            var value = this.vm.data[this.exp];
            Dep.target = null;
            return value;
        }
    };

    function Compile(el, vm) {
        this.vm = vm;
        this.el = document.querySelector(el);
        this.fragment = null;
        this.init();
    }
    Compile.prototype = {
        init: function() {
            if (this.el) {
                this.fragment = this.nodeToFragment(this.el);
                this.compileElement(this.fragment);
                this.el.appendChild(this.fragment);
            } else {
                console.log('Dom元素不存在');
            }
        },
        nodeToFragment: function(el) {
            var fragment = document.createDocumentFragment(),
                child = el.firstChild;
            while (child) {
                fragment.appendChild(child);
                child = el.firstChild;
            }
            return fragment;
        },
        compileElement: function(el) {
            var childNodes = el.childNodes,
                self = this;
            [].slice.call(childNodes).forEach(function(node) {
                var reg = /\{\{(.*)\}\}/,
                    text = node.textContent;
                if (self.isElementNode(node)) {
                    self.compile(node);
                } else if (self.isTextNode(node) && reg.test(text)) {
                    self.compileText(node, reg.exec(text)[1]);
                }
                if (node.childNodes && node.childNodes.length) {
                    self.compileElement(node);
                }
            });
        },
        compile: function(node) {
            var nodeAttrs = node.attributes,
                self = this;
            Array.prototype.forEach.call(nodeAttrs, function(attr) {
                var attrName = attr.name;
                if (self.isDirective(attrName)) {
                    var exp = attr.value,
                        dir = attrName.substring(2);
                    if (self.isEventDirective(dir)) {
                        self.compileEvent(node, self.vm, exp, dir);
                    } else {
                        self.compileModel(node, self.vm, exp, dir);
                    }
                    node.removeAttribute(attrName);
                }
            });
        },
        compileText: function(node, exp) {
            var self = this,
                initText = this.vm[exp];
            this.updateText(node, initText);
            new Watcher(this.vm, exp, function(value) {
                self.updateText(node, value);
            });
        },
        compileEvent: function(node, vm, exp, dir) {
            var eventType = dir.split(':')[1],
                cb = vm.methods && vm.methods[exp];
            if (eventType && cb) {
                node.addEventListener(eventType, cb.bind(vm), false);
            }
        },
        compileModel: function(node, vm, exp, dir) {
            var self = this,
                val = this.vm[exp];
            this.modelUpdater(node, val);
            new Watcher(this.vm, exp, function(value) {
                self.modelUpdater(node, value);
            });
            node.addEventListener('input', function(e) {
                var newValue = e.target.value;
                if (val === newValue) {
                    return;
                }
                self.vm[exp] = newValue;
                val = newValue;
            });
        },
        updateText: function(node, value) {
            node.textContent = typeof value == 'undefined' ? '' : value;
        },
        modelUpdater: function(node, value, oldValue) {
            node.value = typeof value == 'undefined' ? '' : value;
        },
        isDirective: function(attr) {
            return attr.indexOf('z-') == 0;
        },
        isEventDirective: function(dir) {
            return dir.indexOf('on:') === 0;
        },
        isElementNode: function(node) {
            return node.nodeType == 1;
        },
        isTextNode: function(node) {
            return node.nodeType == 3;
        }
    };
    $data.prototype = {
        proxyKeys: function(key) {
            var self = this;
            Object.defineProperty(this, key, {
                enumerable: false,
                configurable: true,
                get: function getter() {
                    return self.data[key];
                },
                set: function setter(newVal) {
                    self.data[key] = newVal;
                }
            });
        }
    };

    function createxmlHttpRequest() {
        if (window.ActiveXObject) {
            return new ActiveXObject("Microsoft.XMLHTTP");
        } else if (window.XMLHttpRequest) {
            return new XMLHttpRequest();
        }
    }

    function convertData(data) {
        if (typeof data === 'object') {
            var convertResult = "";
            for (let c in data) {
                convertResult += c + "=" + data[c] + "&";
            }
            convertResult = convertResult.substring(0, convertResult.length - 1);
            return convertResult;
        } else {
            return data;
        }
    }

    function removeWhiteNode(node) {
        for (let i = 0; i < node.childNodes.length; i++) {
            if (node.childNodes[i].nodeType === 3 && /^\s+$/.test(node.childNodes[i].nodeValue)) {
                node.childNodes[i].parentNode.removeChild(node.childNodes[i]);
            }
        }
        return node;
    }

    function hexToRgb(hex) {
        var color = [],
            rgb = [];
        hex = hex.replace(/#/, "");
        if (hex.length === 3) {
            var tmp = [];
            for (let i = 0; i < 3; i++) {
                tmp.push(hex.charAt(i) + hex.charAt(i));
            }
            hex = tmp.join("");
        }
        for (let i = 0; i < 3; i++) {
            color[i] = "0x" + hex.substr(i + 2, 2);
            rgb.push(parseInt(Number(color[i])));
        }
        return "rgb(" + rgb.join(", ") + ")";
    }

    function colorToRgb(str) {
        if (str && typeof str === 'string') {
            if (str === "lightpink") {
                return str = "rgb(255, 182, 193)";
            } else if (str === "pink") {
                return str = "rgb(255, 192, 203)";
            } else if (str === "crimson") {
                return str = "rgb(220, 20, 60)";
            } else if (str === "lavenderblush") {
                return str = "rgb(255, 240, 245)";
            } else if (str === "palevioletred") {
                return str = "rgb(219, 112, 147)";
            } else if (str === "hotpink") {
                return str = "rgb(255, 105, 180)";
            } else if (str === "deeppink") {
                return str = "rgb(255, 20, 147)";
            } else if (str === "mediumvioletred") {
                return str = "rgb(199, 21, 133)";
            } else if (str === "orchid") {
                return str = "rgb(218, 112, 214)";
            } else if (str === "thistle") {
                return str = "rgb(216, 191, 216)";
            } else if (str === "plum") {
                return str = "rgb(221, 160, 221)";
            } else if (str === "violet") {
                return str = "rgb(238, 130, 238)";
            } else if (str === "magenta") {
                return str = "rgb(255, 0, 255)";
            } else if (str === "fuchsia") {
                return str = "rgb(255, 0, 255)";
            } else if (str === "darkmagenta") {
                return str = "rgb(139, 0, 139)";
            } else if (str === "purple") {
                return str = "rgb(128, 0, 128)";
            } else if (str === "mediumorchid") {
                return str = "rgb(186, 85, 211)";
            } else if (str === "darkvoilet") {
                return str = "rgb(148, 0, 211)";
            } else if (str === "darkorchid") {
                return str = "rgb(153, 50, 204)";
            } else if (str === "indigo") {
                return str = "rgb(75, 0, 130)";
            } else if (str === "blueviolet") {
                return str = "rgb(138, 43, 226)";
            } else if (str === "mediumpurple") {
                return str = "rgb(147, 112, 219)";
            } else if (str === "mediumslateblue") {
                return str = "rgb(123, 104, 238)";
            } else if (str === "slateblue") {
                return str = "rgb(106, 90, 205)";
            } else if (str === "darkslateblue") {
                return str = "rgb(72, 61, 139)";
            } else if (str === "lavender") {
                return str = "rgb(230, 230, 250)";
            } else if (str === "ghostwhite") {
                return str = "rgb(248, 248, 255)";
            } else if (str === "blue") {
                return str = "rgb(0, 0, 255)";
            } else if (str === "mediumblue") {
                return str = "rgb(0, 0, 205)";
            } else if (str === "midnightblue") {
                return str = "rgb(25, 25, 112)";
            } else if (str === "darkblue") {
                return str = "rgb(0, 0, 139)";
            } else if (str === "navy") {
                return str = "rgb(0, 0, 128)";
            } else if (str === "royalblue") {
                return str = "rgb(65, 105, 225)";
            } else if (str === "cornflowerblue") {
                return str = "rgb(100, 149, 237)";
            } else if (str === "lightsteelblue") {
                return str = "rgb(176, 196, 222)";
            } else if (str === "lightslategray" || str === "lightslategrey") {
                return str = "rgb(119, 136, 153)";
            } else if (str === "slategray" || str === "slategrey") {
                return str = "rgb(112, 128, 144)";
            } else if (str === "doderblue") {
                return str = "rgb(30, 144, 255)";
            } else if (str === "aliceblue") {
                return str = "rgb(240, 248, 255)";
            } else if (str === "steelblue") {
                return str = "rgb(70, 130, 180)";
            } else if (str === "lightskyblue") {
                return str = "rgb(135, 206, 250)";
            } else if (str === "skyblue") {
                return str = "rgb(135, 206, 235)";
            } else if (str === "deepskyblue") {
                return str = "rgb(0, 191, 255)";
            } else if (str === "lightblue") {
                return str = "rgb(173, 216, 230)";
            } else if (str === "powderblue") {
                return str = "rgb(176, 224, 230)";
            } else if (str === "cadetblue") {
                return str = "rgb(95, 158, 160)";
            } else if (str === "azure") {
                return str = "rgb(240, 255, 255)";
            } else if (str === "lightcyan") {
                return str = "rgb(225, 255, 255)";
            } else if (str === "paleturquoise") {
                return str = "rgb(175, 238, 238)";
            } else if (str === "cyan") {
                return str = "rgb(0, 255, 255)";
            } else if (str === "aqua") {
                return str = "rgb(0, 255, 255)";
            } else if (str === "darkturquoise") {
                return str = "rgb(0, 206, 209)";
            } else if (str === "darkslategray" || str === "darkslategrey") {
                return str = "rgb(47, 79, 79)";
            } else if (str === "darkcyan") {
                return str = "rgb(0, 139, 139)";
            } else if (str === "teal") {
                return str = "rgb(0, 128, 128)";
            } else if (str === "mediumturquoise") {
                return str = "rgb(72, 209, 204)";
            } else if (str === "lightseagreen") {
                return str = "rgb(32, 178, 170)";
            } else if (str === "turquoise") {
                return str = "rgb(64, 224, 208)";
            } else if (str === "auqamarin") {
                return str = "rgb(127, 255, 170)";
            } else if (str === "mediumaquamarine") {
                return str = "rgb(0, 250, 154)";
            } else if (str === "mediumspringgreen") {
                return str = "rgb(245, 255, 250)";
            } else if (str === "mintcream") {
                return str = "rgb(0, 255, 127)";
            } else if (str === "springgreen") {
                return str = "rgb(60, 179, 113)";
            } else if (str === "seagreen") {
                return str = "rgb(46, 139, 87)";
            } else if (str === "honeydew") {
                return str = "rgb(240, 255, 240)";
            } else if (str === "lightgreen") {
                return str = "rgb(144, 238, 144)";
            } else if (str === "palegreen") {
                return str = "rgb(152, 251, 152)";
            } else if (str === "darkseagreen") {
                return str = "rgb(143, 188, 143)";
            } else if (str === "limegreen") {
                return str = "rgb(50, 205, 50)";
            } else if (str === "lime") {
                return str = "rgb(0, 255, 0)";
            } else if (str === "forestgreen") {
                return str = "rgb(34, 139, 34)";
            } else if (str === "green") {
                return str = "rgb(0, 128, 0)";
            } else if (str === "darkgreen") {
                return str = "rgb(0, 100, 0)";
            } else if (str === "chartreuse") {
                return str = "rgb(127, 255, 0)";
            } else if (str === "lawngreen") {
                return str = "rgb(124, 252, 0)";
            } else if (str === "greenyellow") {
                return str = "rgb(173, 255, 47)";
            } else if (str === "olivedrab") {
                return str = "rgb(85, 107, 47)";
            } else if (str === "beige") {
                return str = "rgb(107, 142, 35)";
            } else if (str === "lightgoldenrodyellow") {
                return str = "rgb(250, 250, 210)";
            } else if (str === "ivory") {
                return str = "rgb(255, 255, 240)";
            } else if (str === "lightyellow") {
                return str = "rgb(255, 255, 224)";
            } else if (str === "yellow") {
                return str = "rgb(255, 255, 0)";
            } else if (str === "olive") {
                return str = "rgb(128, 128, 0)";
            } else if (str === "darkkhaki") {
                return str = "rgb(189, 183, 107)";
            } else if (str === "lemonchelse iffon") {
                return str = "rgb(255, 250, 205)";
            } else if (str === "palegodenrod") {
                return str = "rgb(238, 232, 170)";
            } else if (str === "khaki") {
                return str = "rgb(240, 230, 140)";
            } else if (str === "gold") {
                return str = "rgb(255, 215, 0)";
            } else if (str === "cornislk") {
                return str = "rgb(255, 248, 220)";
            } else if (str === "goldenrod") {
                return str = "rgb(218, 165, 32)";
            } else if (str === "floralwhite") {
                return str = "rgb(255, 250, 240)";
            } else if (str === "oldlace") {
                return str = "rgb(253, 245, 230)";
            } else if (str === "wheat") {
                return str = "rgb(245, 222, 179)";
            } else if (str === "moccasin") {
                return str = "rgb(255, 228, 181)";
            } else if (str === "orange") {
                return str = "rgb(255, 165, 0)";
            } else if (str === "papayawhip") {
                return str = "rgb(255, 239, 213)";
            } else if (str === "blanchedalmond") {
                return str = "rgb(255, 235, 205)";
            } else if (str === "navajowhite") {
                return str = "rgb(255, 222, 173)";
            } else if (str === "antiquewhite") {
                return str = "rgb(250, 235, 215)";
            } else if (str === "tan") {
                return str = "rgb(210, 180, 140)";
            } else if (str === "brulywood") {
                return str = "rgb(222, 184, 135)";
            } else if (str === "bisque") {
                return str = "rgb(255, 228, 196)";
            } else if (str === "darkorange") {
                return str = "rgb(255, 140, 0)";
            } else if (str === "linen") {
                return str = "rgb(250, 240, 230)";
            } else if (str === "peru") {
                return str = "rgb(205, 133, 63)";
            } else if (str === "peachpuff") {
                return str = "rgb(255, 218, 185)";
            } else if (str === "sandybrown") {
                return str = "rgb(244, 164, 96)";
            } else if (str === "chocolate") {
                return str = "rgb(210, 105, 30)";
            } else if (str === "saddlebrown") {
                return str = "rgb(139, 69, 19)";
            } else if (str === "seashell") {
                return str = "rgb(255, 245, 238)";
            } else if (str === "sienna") {
                return str = "rgb(160, 82, 45)";
            } else if (str === "lightsalmon") {
                return str = "rgb(255, 160, 122)";
            } else if (str === "coral") {
                return str = "rgb(255, 127, 80)";
            } else if (str === "orangered") {
                return str = "rgb(255, 69, 0)";
            } else if (str === "darksalmon") {
                return str = "rgb(233, 150, 122)";
            } else if (str === "tomato") {
                return str = "rgb(255, 99, 71)";
            } else if (str === "mistyrose") {
                return str = "rgb(255, 228, 225)";
            } else if (str === "salmon") {
                return str = "rgb(250, 128, 114)";
            } else if (str === "snow") {
                return str = "rgb(255, 250, 250)";
            } else if (str === "lightcoral") {
                return str = "rgb(240, 128, 128)";
            } else if (str === "rosybrown") {
                return str = "rgb(188, 143, 143)";
            } else if (str === "indianred") {
                return str = "rgb(205, 92, 92)";
            } else if (str === "red") {
                return str = "rgb(255, 0, 0)";
            } else if (str === "brown") {
                return str = "rgb(165, 42, 42)";
            } else if (str === "firebrick") {
                return str = "rgb(178, 34, 34)";
            } else if (str === "darkred") {
                return str = "rgb(139, 0, 0)";
            } else if (str === "maroon") {
                return str = "rgb(128, 0, 0)";
            } else if (str === "white") {
                return str = "rgb(255, 255, 255)";
            } else if (str === "whitesmoke") {
                return str = "rgb(245, 245, 245)";
            } else if (str === "gainsboro") {
                return str = "rgb(220, 220, 220)";
            } else if (str === "lightgrey" || str === "lightgray") {
                return str = "rgb(211, 211, 211)";
            } else if (str === "silver") {
                return str = "rgb(192, 192, 192)";
            } else if (str === "darkgray" || str === "darkgrey") {
                return str = "rgb(169, 169, 169)";
            } else if (str === "gray" || str === "grey") {
                return str = "rgb(128, 128, 128)";
            } else if (str === "dimgray" || str === "dimgrey") {
                return str = "rgb(105, 105, 105)";
            } else if (str === "black") {
                return str = "rgb(0, 0, 0)";
            }
        }
    }

    function isBlock(obj) {
        if (obj.tagName === 'ADDRESS' || obj.tagName === 'CAPTION' || obj.tagName === 'DD' || obj.tagName === 'DIV' || obj.tagName === 'DL' || obj.tagName === 'DT' || obj.tagName === 'FIELDSET' || obj.tagName === 'FORM' || obj.tagName === 'H1' || obj.tagName === 'H2' || obj.tagName === 'H3' || obj.tagName === 'H4' || obj.tagName === 'H5' || obj.tagName === 'H6' || obj.tagName === 'HR' || obj.tagName === 'LEGEND' || obj.tagName === 'LI' || obj.tagName === 'NOFRAMES' || obj.tagName === 'NOSCRIPT' || obj.tagName === 'OL' || obj.tagName === 'UL' || obj.tagName === 'P' || obj.tagName === 'PRE' || obj.tagName === 'TABLE' || obj.tagName === 'TBODY' || obj.tagName === 'TD' || obj.tagName === 'TFOOT' || obj.tagName === 'TH' || obj.tagName === 'THEAD' || obj.tagName === 'TR' || obj.tagName === 'BODY') {
            return 1;
        } else {
            return 0;
        }
    }

    function nextnode(obj) {
        if (obj.nextElementSibling) {
            return obj.nextElementSibling;
        } else {
            return obj.nextSibling;
        }
    }

    function prenode(obj) {
        if (obj.previousElementSibling) {
            return obj.previousElementSibling;
        } else {
            return obj.previousSibling;
        }
    }

    function firstnode(obj) {
        if (obj.firstElementChild) {
            return obj.firstElementChild;
        } else {
            return obj.firstChild;
        }
    }

    function lastnode(obj) {
        if (obj.lastElementChild) {
            return obj.lastElementChild;
        } else {
            return obj.lastChild;
        }
    }

    function setOpacity(elem, opacity) {
        if (elem.style.filter) {
            elem.style.filter = 'alpha(opacity:' + opacity * 100 + ')';
        } else {
            elem.style.opacity = opacity;
        }
    }
    if (!Array.prototype.copyWithin) {
        Array.prototype.copyWithin = function(target, start) {
            if (this === null) {
                throw new TypeError('this is null or not defined');
            }
            var O = Object(this),
                len = O.length >>> 0,
                relativeTarget = target >> 0,
                to = relativeTarget < 0 ? Math.max(len + relativeTarget, 0) : Math.min(relativeTarget, len),
                relativeStart = start >> 0,
                from = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len),
                end = arguments[2],
                relativeEnd = end === undefined ? len : end >> 0,
                final = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len),
                count = Math.min(final - from, len - to),
                direction = 1;
            if (from < to && to < (from + count)) {
                direction = -1;
                from += count - 1;
                to += count - 1;
            }
            while (count > 0) {
                if (from in O) {
                    O[to] = O[from];
                } else {
                    delete O[to];
                }
                from += direction;
                to += direction;
                count--;
            }
            return O;
        }
    }
    if (!Array.from) {
        Array.from = (function() {
            var toStr = Object.prototype.toString,
                isCallable = function(fn) {
                    return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
                },
                toInteger = function(value) {
                    var number = Number(value);
                    if (isNaN(number)) {
                        return 0;
                    }
                    if (number === 0 || !isFinite(number)) {
                        return number;
                    }
                    return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
                },
                maxSafeInteger = Math.pow(2, 53) - 1,
                toLength = function(value) {
                    var len = toInteger(value);
                    return Math.min(Math.max(len, 0), maxSafeInteger);
                }
            return function from(arrayLike) {
                var C = this,
                    items = Object(arrayLike);
                if (arrayLike === null) {
                    throw new TypeError("Array.from requires an array-like object - not null or undefined");
                }
                var mapFn = arguments.length > 1 ? arguments[1] : void undefined,
                    T;
                if (typeof mapFn !== 'undefined') {
                    if (!isCallable(mapFn)) {
                        throw new TypeError('Array.from: when provided, the second argument must be a function');
                    }
                    if (arguments.length > 2) {
                        T = arguments[2];
                    }
                }
                var len = toLength(items.length),
                    A = isCallable(C) ? Object(new C(len)) : new Array(len),
                    k = 0,
                    kValue;
                while (k < len) {
                    kValue = items[k];
                    if (mapFn) {
                        A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
                    } else {
                        A[k] = kValue;
                    }
                    k += 1;
                }
                A.length = len;
                return A;
            }
        }());
    }
    if (!Array.isArray) {
        Array.isArray = function(arg) {
            return Object.prototype.toString.call(arg) === '[object Array]';
        }
    }
    if (!Array.of) {
        Array.of = function() {
            return Array.prototype.slice.call(arguments);
        }
    }
    if (!Array.prototype.every) {
        Array.prototype.every = function(fun) {
            'use strict';
            if (this === void 0 || this === null)
                throw new TypeError();
            var t = Object(this),
                len = t.length >>> 0;
            if (typeof fun !== 'function')
                throw new TypeError();
            var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
            for (let i = 0; i < len; i++) {
                if (i in t && !fun.call(thisArg, t[i], i, t))
                    return false;
            }
            return true;
        }
    }
    if (!Array.prototype.fill) {
        Array.prototype.fill = function(value) {
            if (this === null) {
                throw new TypeError('this is null or not defined');
            }
            var O = Object(this),
                len = O.length >>> 0,
                start = arguments[1],
                relativeStart = start >> 0,
                k = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len),
                end = arguments[2],
                relativeEnd = end === undefined ? len : end >> 0,
                final = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len);
            while (k < final) {
                O[k] = value;
                k++;
            }
            return O;
        }
    }
    if (!Array.prototype.filter) {
        Array.prototype.filter = function(fun) {
            "use strict";
            if (this === void 0 || this === null)
                throw new TypeError();
            var t = Object(this),
                len = t.length >>> 0;
            if (typeof fun !== "function")
                throw new TypeError();
            var res = [],
                thisArg = arguments.length >= 2 ? arguments[1] : void 0;
            for (let i = 0; i < len; i++) {
                if (i in t) {
                    var val = t[i];
                    if (fun.call(thisArg, val, i, t))
                        res.push(val);
                }
            }
            return res;
        }
    }
    if (!Array.prototype.find) {
        Array.prototype.find = function(predicate) {
            'use strict';
            if (this === null) {
                throw new TypeError('Array.prototype.find called on null or undefined');
            }
            if (typeof predicate !== 'function') {
                throw new TypeError('predicate must be a function');
            }
            var list = Object(this),
                length = list.length >>> 0,
                thisArg = arguments[1],
                value;
            for (let i = 0; i < length; i++) {
                value = list[i];
                if (predicate.call(thisArg, value, i, list)) {
                    return value;
                }
            }
            return undefined;
        }
    }
    if (!Array.prototype.findIndex) {
        Array.prototype.findIndex = function(predicate) {
            if (this === null) {
                throw new TypeError('Array.prototype.findIndex called on null or undefined');
            }
            if (typeof predicate !== 'function') {
                throw new TypeError('predicate must be a function');
            }
            var list = Object(this),
                length = list.length >>> 0,
                thisArg = arguments[1],
                value;
            for (let i = 0; i < length; i++) {
                value = list[i];
                if (predicate.call(thisArg, value, i, list)) {
                    return i;
                }
            }
            return -1;
        }
    }
    if (!Array.prototype.forEach) {
        Array.prototype.forEach = function(callback, thisArg) {
            var T, k;
            if (this === null) {
                throw new TypeError(' this is null or not defined');
            }
            var O = Object(this),
                len = O.length >>> 0;
            if (typeof callback !== "function") {
                throw new TypeError(callback + ' is not a function');
            }
            if (arguments.length > 1) {
                T = thisArg;
            }
            k = 0;
            while (k < len) {
                var kValue;
                if (k in O) {
                    kValue = O[k];
                    callback.call(T, kValue, k, O);
                }
                k++;
            }
        }
    }
    if (!Array.prototype.includes) {
        Object.defineProperty(Array.prototype, 'includes', {
            value: function(searchElement, fromIndex) {
                if (this === null) {
                    throw new TypeError('"this" is null or not defined');
                }
                var o = Object(this),
                    len = o.length >>> 0;
                if (len === 0) {
                    return false;
                }
                var n = fromIndex | 0,
                    k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
                while (k < len) {
                    if (o[k] === searchElement) {
                        return true;
                    }
                    k++;
                }
                return false;
            }
        });
    }
    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function(searchElement, fromIndex) {
            var k;
            if (this === null) {
                throw new TypeError('"this" is null or not defined');
            }
            var O = Object(this),
                len = O.length >>> 0;
            if (len === 0) {
                return -1;
            }
            var n = +fromIndex || 0;
            if (Math.abs(n) === Infinity) {
                n = 0;
            }
            if (n >= len) {
                return -1;
            }
            k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
            while (k < len) {
                if (k in O && O[k] === searchElement) {
                    return k;
                }
                k++;
            }
            return -1;
        }
    }
    if (!Array.prototype.lastIndexOf) {
        Array.prototype.lastIndexOf = function(searchElement) {
            'use strict';
            if (this === void 0 || this === null) {
                throw new TypeError();
            }
            var n, k,
                t = Object(this),
                len = t.length >>> 0;
            if (len === 0) {
                return -1;
            }
            n = len - 1;
            if (arguments.length > 1) {
                n = Number(arguments[1]);
                if (n != n) {
                    n = 0;
                } else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) {
                    n = (n > 0 || -1) * Math.floor(Math.abs(n));
                }
            }
            for (k = n >= 0 ?
                Math.min(n, len - 1) :
                len - Math.abs(n); k >= 0; k--) {
                if (k in t && t[k] === searchElement) {
                    return k;
                }
            }
            return -1;
        }
    }
    if (!Array.prototype.map) {
        Array.prototype.map = function(callback, thisArg) {
            var T, A, k;
            if (this === null) {
                throw new TypeError(" this is null or not defined");
            }
            var O = Object(this),
                len = O.length >>> 0;
            if (Object.prototype.toString.call(callback) != "[object Function]") {
                throw new TypeError(callback + " is not a function");
            }
            if (thisArg) {
                T = thisArg;
            }
            A = new Array(len);
            k = 0;
            while (k < len) {
                var kValue, mappedValue;
                if (k in O) {
                    kValue = O[k];
                    mappedValue = callback.call(T, kValue, k, O);
                    A[k] = mappedValue;
                }
                k++;
            }
            return A;
        }
    }
    if (!Array.prototype.reduce) {
        Array.prototype.reduce = function(callback) {
            'use strict';
            if (this === null) {
                throw new TypeError('Array.prototype.reduce called on null or undefined');
            }
            if (typeof callback !== 'function') {
                throw new TypeError(callback + ' is not a function');
            }
            var t = Object(this),
                len = t.length >>> 0,
                k = 0,
                value;
            if (arguments.length >= 2) {
                value = arguments[1];
            } else {
                while (k < len && !(k in t)) {
                    k++;
                }
                if (k >= len) {
                    throw new TypeError('Reduce of empty array with no initial value');
                }
                value = t[k++];
            }
            for (; k < len; k++) {
                if (k in t) {
                    value = callback(value, t[k], k, t);
                }
            }
            return value;
        }
    }
    if ('function' !== typeof Array.prototype.reduceRight) {
        Array.prototype.reduceRight = function(callback) {
            'use strict';
            if (null === this || 'undefined' === typeof this) {
                throw new TypeError('Array.prototype.reduce called on null or undefined');
            }
            if ('function' !== typeof callback) {
                throw new TypeError(callback + ' is not a function');
            }
            var t = Object(this),
                len = t.length >>> 0,
                k = len - 1,
                value;
            if (arguments.length >= 2) {
                value = arguments[1];
            } else {
                while (k >= 0 && !(k in t)) {
                    k--;
                }
                if (k < 0) {
                    throw new TypeError('Reduce of empty array with no initial value');
                }
                value = t[k--];
            }
            for (; k >= 0; k--) {
                if (k in t) {
                    value = callback(value, t[k], k, t);
                }
            }
            return value;
        }
    }
    if (!Object.defineProperties) {
        Object.defineProperties = function(obj, properties) {
            function convertToDescriptor(desc) {
                function hasProperty(obj, prop) {
                    return Object.prototype.hasOwnProperty.call(obj, prop);
                }

                function isCallable(v) {
                    return typeof v === "function";
                }
                if (typeof desc !== "object" || desc === null)
                    throw new TypeError("不是正规的对象");
                var d = {}
                if (hasProperty(desc, "enumerable"))
                    d.enumerable = !!desc.enumerable;
                if (hasProperty(desc, "configurable"))
                    d.configurable = !!desc.configurable;
                if (hasProperty(desc, "value"))
                    d.value = desc.value;
                if (hasProperty(desc, "writable"))
                    d.writable = !!desc.writable;
                if (hasProperty(desc, "get")) {
                    var g = desc.get;
                    if (!isCallable(g) && g !== "undefined")
                        throw new TypeError("bad get");
                    d.get = g;
                }
                if (hasProperty(desc, "set")) {
                    var s = desc.set;
                    if (!isCallable(s) && s !== "undefined")
                        throw new TypeError("bad set");
                    d.set = s;
                }
                if (("get" in d || "set" in d) && ("value" in d || "writable" in d))
                    throw new TypeError("identity-confused descriptor");
                return d;
            }
            if (typeof obj !== "object" || obj === null)
                throw new TypeError("不是正规的对象");
            properties = Object(properties);
            var keys = Object.keys(properties),
                descs = [];
            for (let i = 0; i < keys.length; i++)
                descs.push([keys[i], convertToDescriptor(properties[keys[i]])]);
            for (let i = 0; i < descs.length; i++)
                Object.defineProperty(obj, descs[i][0], descs[i][1]);
            return obj;
        }
    }
    if (!Object.assign) {
        Object.defineProperty(Object, "assign", {
            enumerable: false,
            configurable: true,
            writable: true,
            value: function(target, firstSource) {
                "use strict";
                if (target === undefined || target === null)
                    throw new TypeError("Cannot convert first argument to object");
                var to = Object(target);
                for (let i = 1; i < arguments.length; i++) {
                    var nextSource = arguments[i];
                    if (nextSource === undefined || nextSource === null) continue;
                    var keysArray = Object.keys(Object(nextSource));
                    for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
                        var nextKey = keysArray[nextIndex],
                            desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
                        if (desc !== undefined && desc.enumerable) to[nextKey] = nextSource[nextKey];
                    }
                }
                return to;
            }
        });
    }
    if (typeof Object.create != 'function') {
        Object.create = (function() {
            function Temp() {}
            var hasOwn = Object.prototype.hasOwnProperty;
            return function(O) {
                if (typeof O != 'object') {
                    throw TypeError('Object prototype may only be an Object or null');
                }
                Temp.prototype = O;
                var obj = new Temp();
                Temp.prototype = null;
                if (arguments.length > 1) {
                    var Properties = Object(arguments[1]);
                    for (let prop in Properties) {
                        if (hasOwn.call(Properties, prop)) {
                            obj[prop] = Properties[prop];
                        }
                    }
                }
                return obj;
            }
        })();
    }
    if (!Object.is) {
        Object.is = function(x, y) {
            if (x === y) {
                return x !== 0 || 1 / x === 1 / y;
            } else {
                return x !== x && y !== y;
            }
        }
    }
    if (!Object.keys) {
        Object.keys = (function() {
            var hasOwnProperty = Object.prototype.hasOwnProperty,
                hasDontEnumBug = !({
                    toString: null
                }).propertyIsEnumerable('toString'),
                dontEnums = [
                    'toString',
                    'toLocaleString',
                    'valueOf',
                    'hasOwnProperty',
                    'isPrototypeOf',
                    'propertyIsEnumerable',
                    'constructor'
                ],
                dontEnumsLength = dontEnums.length;
            return function(obj) {
                if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
                var result = [];
                for (let prop in obj) {
                    if (hasOwnProperty.call(obj, prop)) result.push(prop);
                }
                if (hasDontEnumBug) {
                    for (let i = 0; i < dontEnumsLength; i++) {
                        if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
                    }
                }
                return result;
            }
        })();
    }
    if (!String.fromCodePoint) {
        (function() {
            var defineProperty = (function() {
                try {
                    var object = {},
                        $defineProperty = Object.defineProperty,
                        result = $defineProperty(object, object, object) && $defineProperty;
                } catch (error) {}
                return result;
            }());
            var stringFromCharCode = String.fromCharCode,
                floor = Math.floor,
                fromCodePoint = function() {
                    var MAX_SIZE = 0x4000,
                        codeUnits = [],
                        highSurrogate,
                        lowSurrogate,
                        index = -1,
                        length = arguments.length;
                    if (!length) {
                        return '';
                    }
                    var result = '';
                    while (++index < length) {
                        var codePoint = Number(arguments[index]);
                        if (!isFinite(codePoint) || codePoint < 0 || codePoint > 0x10FFFF || floor(codePoint) != codePoint) {
                            throw RangeError('Invalid code point: ' + codePoint);
                        }
                        if (codePoint <= 0xFFFF) {
                            codeUnits.push(codePoint);
                        } else {
                            codePoint -= 0x10000;
                            highSurrogate = (codePoint >> 10) + 0xD800;
                            lowSurrogate = (codePoint % 0x400) + 0xDC00;
                            codeUnits.push(highSurrogate, lowSurrogate);
                        }
                        if (index + 1 === length || codeUnits.length > MAX_SIZE) {
                            result += stringFromCharCode.apply(null, codeUnits);
                            codeUnits.length = 0;
                        }
                    }
                    return result;
                }
            if (defineProperty) {
                defineProperty(String, 'fromCodePoint', {
                    'value': fromCodePoint,
                    'configurable': true,
                    'writable': true
                });
            } else {
                String.fromCodePoint = fromCodePoint;
            }
        }());
    }
    if (!String.prototype.codePointAt) {
        (function() {
            'use strict';
            var codePointAt = function(position) {
                if (this === null) {
                    throw TypeError();
                }
                var string = String(this),
                    size = string.length,
                    index = position ? Number(position) : 0;
                if (index != index) {
                    index = 0;
                }
                if (index < 0 || index >= size) {
                    return undefined;
                }
                var first = string.charCodeAt(index),
                    second;
                if (
                    first >= 0xD800 && first <= 0xDBFF &&
                    size > index + 1
                ) {
                    second = string.charCodeAt(index + 1);
                    if (second >= 0xDC00 && second <= 0xDFFF) {
                        return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
                    }
                }
                return first;
            }
            if (Object.defineProperty) {
                Object.defineProperty(String.prototype, 'codePointAt', {
                    'value': codePointAt,
                    'configurable': true,
                    'writable': true
                });
            } else {
                String.prototype.codePointAt = codePointAt;
            }
        }());
    }
    if (!String.prototype.startsWith) {
        (function() {
            'use strict';
            var defineProperty = (function() {
                try {
                    var object = {},
                        $defineProperty = Object.defineProperty,
                        result = $defineProperty(object, object, object) && $defineProperty;
                } catch (error) {}
                return result;
            }());
            var toString = {}.toString,
                startsWith = function(search) {
                    if (this === null) {
                        throw TypeError();
                    }
                    var string = String(this);
                    if (search && toString.call(search) === '[object RegExp]') {
                        throw TypeError();
                    }
                    var stringLength = string.length,
                        searchString = String(search),
                        searchLength = searchString.length,
                        position = arguments.length > 1 ? arguments[1] : undefined,
                        pos = position ? Number(position) : 0;
                    if (pos != pos) {
                        pos = 0;
                    }
                    var start = Math.min(Math.max(pos, 0), stringLength);
                    if (searchLength + start > stringLength) {
                        return false;
                    }
                    var index = -1;
                    while (++index < searchLength) {
                        if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {
                            return false;
                        }
                    }
                    return true;
                }
            if (defineProperty) {
                defineProperty(String.prototype, 'startsWith', {
                    'value': startsWith,
                    'configurable': true,
                    'writable': true
                });
            } else {
                String.prototype.startsWith = startsWith;
            }
        }());
    }
    if (!String.prototype.endsWith) {
        (function() {
            'use strict';
            var defineProperty = (function() {
                try {
                    var object = {},
                        $defineProperty = Object.defineProperty,
                        result = $defineProperty(object, object, object) && $defineProperty;
                } catch (error) {}
                return result;
            }());
            var toString = {}.toString,
                endsWith = function(search) {
                    if (this === null) {
                        throw TypeError();
                    }
                    var string = String(this);
                    if (search && toString.call(search) === '[object RegExp]') {
                        throw TypeError();
                    }
                    var stringLength = string.length,
                        searchString = String(search),
                        searchLength = searchString.length,
                        pos = stringLength;
                    if (arguments.length > 1) {
                        var position = arguments[1];
                        if (position !== undefined) {
                            pos = position ? Number(position) : 0;
                            if (pos != pos) {
                                pos = 0;
                            }
                        }
                    }
                    var end = Math.min(Math.max(pos, 0), stringLength),
                        start = end - searchLength;
                    if (start < 0) {
                        return false;
                    }
                    var index = -1;
                    while (++index < searchLength) {
                        if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {
                            return false;
                        }
                    }
                    return true;
                }
            if (defineProperty) {
                defineProperty(String.prototype, 'endsWith', {
                    'value': endsWith,
                    'configurable': true,
                    'writable': true
                });
            } else {
                String.prototype.endsWith = endsWith;
            }
        }());
    }
    if (!String.prototype.repeat) {
        String.prototype.repeat = function(count) {
            'use strict';
            if (this === null) {
                throw new TypeError('can\'t convert ' + this + ' to object');
            }
            var str = '' + this;
            count = +count;
            if (count != count) {
                count = 0;
            }
            if (count < 0) {
                throw new RangeError('repeat count must be non-negative');
            }
            if (count === Infinity) {
                throw new RangeError('repeat count must be less than infinity');
            }
            count = Math.floor(count);
            if (str.length === 0 || count === 0) {
                return '';
            }
            if (str.length * count >= 1 << 28) {
                throw new RangeError('repeat count must not overflow maximum string size');
            }
            var rpt = '';
            for (;;) {
                if ((count & 1) === 1) {
                    rpt += str;
                }
                count >>>= 1;
                if (count === 0) {
                    break;
                }
                str += str;
            }
            return rpt;
        }
    }
    if ('ab'.substr(-1) != 'b') {
        String.prototype.substr = function(substr) {
            return function(start, length) {
                if (start < 0) start = this.length + start;
                return substr.call(this, start, length);
            }
        }(String.prototype.substr);
    }
    if (!String.prototype.includes) {
        String.prototype.includes = function(search, start) {
            'use strict';
            if (typeof start !== 'number') {
                start = 0;
            }
            if (start + search.length > this.length) {
                return false;
            } else {
                return this.indexOf(search, start) !== -1;
            }
        }
    }
    if (!String.prototype.trim) {
        String.prototype.trim = function() {
            return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
        }
    }
    if (!Function.prototype.bind) {
        Function.prototype.bind = function(oThis) {
            if (typeof this !== "function") {
                throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
            }
            var aArgs = Array.prototype.slice.call(arguments, 1),
                fToBind = this,
                fNOP = $noop(),
                fBound = function() {
                    return fToBind.apply(this instanceof fNOP ?
                        this :
                        oThis || this,
                        aArgs.concat(Array.prototype.slice.call(arguments)));
                }
            fNOP.prototype = this.prototype;
            fBound.prototype = new fNOP();
            return fBound;
        }
    }
    if (!Number.isFinite) {
        Number.isFinite = Number.isFinite || function(value) {
            return typeof value === "number" && isFinite(value);
        }
    }
    if (!Number.isInteger) {
        Number.isInteger = Number.isInteger || function(value) {
            return typeof value === "number" &&
                isFinite(value) &&
                Math.floor(value) === value;
        }
    }
    if (!Number.isNaN) {
        Number.isNaN = Number.isNaN || function(value) {
            return typeof value === "number" && isNaN(value);
        }
    }
    if (!Number.isSafeInteger) {
        Number.isSafeInteger = Number.isSafeInteger || function(value) {
            return Number.isInteger(value) && Math.abs(value) <= Number.MAX_SAFE_INTEGER;
        }
    }
    if (window.NodeList && !NodeList.prototype.forEach) {
        NodeList.prototype.forEach = function(callback, argument) {
            argument = argument || window;
            for (let i = 0; i < this.length; i++) {
                callback.call(argument, this[i], i, this);
            }
        }
    }
    (function(DOMParser) {
        "use strict";
        var proto = DOMParser.prototype,
            nativeParse = proto.parseFromString;
        try {
            if ((new DOMParser()).parseFromString("", "text/html")) {
                return;
            }
        } catch (ex) {}
        proto.parseFromString = function(markup, type) {
            if (/^\s*text\/html\s*(?:;|$)/i.test(type)) {
                var doc = document.implementation.createHTMLDocument("");
                if (markup.toLowerCase().indexOf('<!doctype') > -1) {
                    doc.documentElement.innerHTML = markup;
                } else {
                    doc.body.innerHTML = markup;
                }
                return doc;
            } else {
                return nativeParse.apply(this, arguments);
            }
        }
    }(DOMParser));
    (function() {
        var lastTime = 0;
        var vendors = ['webkit', 'moz'];
        for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
            window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
            window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
        }
        if (!window.requestAnimationFrame) {
            window.requestAnimationFrame = function(callback, element) {
                var currTime = new Date().getTime();
                var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
                var id = window.setTimeout(function() {
                    callback(currTime + timeToCall);
                }, timeToCall);
                lastTime = currTime + timeToCall;
                return id;
            }
        }
        if (!window.cancelAnimationFrame) {
            window.cancelAnimationFrame = function(id) {
                clearTimeout(id);
            }
        }
    }());
    if (typeof window === "object" && typeof window.document === "object") {
        window.isChrome = isChrome;
        window.isFF = isFF;
        window.isOpera = isOpera;
        window.isSafari = isSafari;
        window.isIE = isIE;
        window.isEdge = isEdge;
        window.version = version;
        window.Zendollar = Zendollar;
        window.$ = $;
        window.$on = $on;
        window.$off = $off;
        window.$load = $load;
        window.$ready = $ready;
        window.$lag = $lag;
        window.$loadImage = $loadImage;
        window.$per = $per;
        window.$each = $each;
        window.$map = $map;
        window.$unique = $unique;
        window.$make = $make;
        window.$grep = $grep;
        window.$merge = $merge;
        window.$trim = $trim;
        window.$call = $call;
        window.$debounce = $debounce;
        window.$poll = $poll;
        window.$once = $once;
        window.$find = $find;
        window.$matches = $matches;
        window.$query = $query;
        window.$filter = $filter;
        window.$until = $until;
        window.$index = $index;
        window.$inArray = $inArray;
        window.$isParent = $isParent;
        window.$isInViewport = $isInViewport;
        window.$isHit = $isHit;
        window.$isWindow = $isWindow;
        window.$isArray = $isArray;
        window.$isFunction = $isFunction;
        window.$isNumber = $isNumber;
        window.$isString = $isString;
        window.$isBoolean = $isBoolean;
        window.$isObject = $isObject;
        window.$isNull = $isNull;
        window.$isUndefined = $isUndefined;
        window.$is = $is;
        window.$print = $print;
        window.$noop = $noop;
        window.$noConflict = $noConflict;
        window.$eval = $eval;
        window.$time = $time;
        window.$getCSS = $getCSS;
        window.$addCSS = $addCSS;
        window.$setCSS = $setCSS;
        window.$clientWidth = $clientWidth;
        window.$clientHeight = $clientHeight;
        window.$scrollLeft = $scrollLeft;
        window.$scrollTop = $scrollTop;
        window.$scrollWidth = $scrollWidth;
        window.$scrollHeight = $scrollHeight;
        window.$outerWidth = $outerWidth;
        window.$outerHeight = $outerHeight;
        window.$screen = $screen;
        window.$imageSize = $imageSize;
        window.$scrollTo = $scrollTo;
        window.$event = $event;
        window.$extend = $extend;
        window.$deepExtend = $deepExtend;
        window.$data = $data;
        window.$ajax = $ajax;
        window.$setCookie = $setCookie;
        window.$getCookie = $getCookie;
        window.$clearCookie = $clearCookie;
        window.$checkCookie = $checkCookie;
        window.$getURLParam = $getURLParam;
        window.$parseHTML = $parseHTML;
        window.$parseURL = $parseURL;
        window.$JSON = $JSON;
        window.$listener = $listener;
    }
})(window);
